On 05/02/2012 04:01 AM, Tim Starling wrote:
How about frame.args.name as an abbreviation for frame:getArgument('name'):expandTo( 'text/x-mediawiki' ) ?
Yep, that looks good to me. Maybe the specialized wikitext argument variant could be called 'wikitextArgs' so that the general variant can be used for ParserValues instead of the getArgument method?
And how about frame.plainArgs.name as an abbreviation for frame:getArgument('name'):expandTo( 'text/plain' ) ?
Adding more xxxArgs methods does not seem to scale that well, and would introduce a lot of extra method names to remember. It would also encourage users to pick one representation when they would not need to care about it, especially if they just pass through some content.
I know you're not really asking for a review of Parsoid and its interfaces, but I worry as to whether your use of text/plain to indicate wikitext with comments stripped is appropriate.
I am not that happy with the text/plain bit too. text/x-mediawiki with a separate progress or 'processing stage' component might be better, as it would not conflate processing stage with the format. I am using a numerical 'rank' value to track progress internally in Parsoid, but a string would likely be user-friendlier for an external API like this. There is an example for this further down in this post.
If I were to provide Lua with a richer interface to PPFrame::expand(), I would be inclined to support at least some of those flags via named options, rather than rolling them up into a single string parameter. So instead of expandTo( 'text/plain' ) we might have:
frame:getArgument('name'):expand{ expand_args = false, expand_templates = false, respect_noinclude = false, strip_comments = true }
Or, if forwards-compatibility requires that we don't support so many orthogonal options, some of the options could be rolled in together. The preceding could perhaps be written as:
frame:getArgument('name'):expand{ plain = true }
That doesn't preclude the use of overrides:
frame:getArgument('name'):expand{ plain = true, strip_comments = false }
But it does seem like a can of worms.
Some grepping through core and extension code left me with the impression that there are relatively few common sets of flags used. As an example, NO_ARGS and NO_TEMPLATES always seem to be used as a pair in situations where just comment and noinclude (and company) handling is needed.
If there remain use cases for fully orthogonal flags, then those could still be supported with optional (named) argument of course, as you note.
How about providing getArgument(), which will return an opaque ParserValue object with a single method called expand(). This method would theoretically take named parameters, but currently, none are defined. With no parameters, it provides some kind of reasonable template-expanding behaviour. Then frame.args would provide an abbreviated syntax for expand() with no parameters.
Yes, this looks very good to me. ParseValue with a heavily defaulted expand() method should be a good compromise between convenience for the currently common case without compromising the ability to work with other content types, or specify the processing stage through a name or flags. So the 'plain' example could look somewhat like this:
arg:expand( format = 'tokens/x-mediawiki', phase = '0.1_noComments' ) --- named processing phase
The conversion of wikitext or other formats to an opaque value object could be achieved using an object constructor:
--- 'value text' is parsed lazily ParserValue( 'text/x-mediawiki', 'value text', frame )
The frame might be the passed-in parent frame, or a custom one constructed with args assembled from other ParserValues.
Yes, this is an interesting idea. But I think I would prefer the factory to be a frame method rather than a global function.
I'd be happy with that too. Custom child frames could still be created using a frame:newChild method.
Also, again, I am skeptical about the value of using a MIME type. How about an interface allowing either:
frame:newParserValue( 'value text' )
or named arguments:
frame:newParserValue{ text = 'value text', fruitiness = 'high', }
+1, but I think some way to indicate the type and processing state of the passed-in value will be needed if non-wikitext values are to be supported. Further processing of a ParserValue depends on this knowledge. Optional (named) arguments could be employed for this too:
frame:newParserValue{ type = 'tokens/x-mediawiki', value = { { type = 'tag', name = 'a', attribs = { href = 'http://foo' } }, "Some link text", { type = 'endtag', name = 'a' } } }
Defaulting to wikitext and fully-preprocessed text for the processing phase would be fine with me. Any kind of type identifiers (MIME or not) could of course be used. MIME has the advantage of being somewhat known already, but other type identifiers might have other advantages.
frame:newTemplateParserValue{title = 'tpl', args = args}:expand()
abbreviated to:
frame:expandTemplate{title = 'tpl', args = args}
+1
It doesn't just make the text shorter, it also reduces the number of concepts that the user has to understand before they are able to use the interface.
I know that adding such concepts gives greater flexibility, but an increase in the number of concepts will steepen the learning curve, and the terminology required to explain them risks being daunting. For example, if someone has never programmed before, you can't expect them to understand terms like "opaque object".
I pretty much agree. The abbreviated interface adds some complication by providing a second way to do the same thing. This still seems to be worth it if it helps people to get started.
Gabriel