Page MenuHomePhabricator

TemplateData: Implement hook for extensions to document magic words and parser functions
Open, LowestPublic

Description

There should be a hook for extensions to return TemplateData JSON for their parser functions (e.g. #babel).


Version: unspecified
Severity: normal
See Also:
https://bugzilla.wikimedia.org/show_bug.cgi?id=50855

Event Timeline

bzimport raised the priority of this task from to High.Nov 22 2014, 1:57 AM
bzimport added a project: TemplateData.
bzimport set Reference to bz52607.

Change 78644 had a related patch set uploaded by Jforrester:
[WIP] Run a hook so extensions can add templatedata for parser functions

https://gerrit.wikimedia.org/r/78644

Rephrasing bug:

Pending T55413 (bug 53413), TemplateData will support magic words and parser functions. This bug is to (after we provide the ones from core) allow extensions to document theirs as well.

Unassigning myself to avoid cookie licking.

Change 78644 abandoned by Legoktm:
[WIP] Run a hook so extensions can add templatedata for parser functions

Reason:
Not planning to work on this

https://gerrit.wikimedia.org/r/78644

Krenair renamed this task from TemplateData: Implement hook for extensions to document parser functions to TemplateData: Implement hook for extensions to document magic words and parser functions.Jan 15 2016, 8:58 PM
Krenair set Security to None.
Deskana lowered the priority of this task from High to Lowest.Feb 23 2018, 4:31 PM

We should probably define a parser function which will invoke a behavior switch (if there isn't one already) so that we can handle behavior switches/magic words/parser functions uniformly: all macro insertions could be expressed using the {{...}} syntax, and the templatedata would be named based on the name inside the braces.

It would seem like you'd want to document parameters for Scribunto modules as well. Although T205197 mostly discusses how it is "best practice" for Scribunto modules to be wrapped in a Template (and so ordinary <templatedata> on the wrapper template would work just fine) it is possible/likely that we will eventually want to use TemplateData as a more-formal type system for fragment composition. In that case it would be useful for internal purposes to be able to document the desired I/O types of {{#invoke}}. Like with {{#tag}} perhaps a hook system is necessary for delegation, so that Scribunto can implement the templatedata for {{#invoke}} programmatically, and then use some properties of the Lua module to compute the appropriate templatedata without requiring explicit definition (alternatively, Scribunto could extract embedded template data from the Module namespace in the same way that Templates extract embedded templatedata from the Template namespace.

So I'm thinking of something like: Parser Function #tag:bar consults both a message in the MediaWiki namespace like MediaWiki:templatedata-pf-tag-bar (if the first arg is a string constant) then falls back to MediaWiki:templatedata-pf-tag as well as provides a registry that can be hooked; something like invoking ProvideTemplateData($name, $optionalFirstArg=null). An extension tag <foo> would in most cases just need to define a default message for MediaWiki:templatedata-pf-tag-foo with appropriate <templatedata>, but Scribunto could implement the ProvideTemplateData hook and listen for $name == 'invoke'.

Technically we could implement ProvideTemplateData internally as well for #tag and have it look aside to a different registry for template data if the tag name corresponds to an extension tag. And maybe our convention should be that we preserve colons when invoking #tag and #invoke in this way to visually signal that the string after the colon is part of the "name" not really an argument (even though T204371 *would* allow a vertical bar there).

This relies on T204370: Behavior switch/magic word uniformity to map "everything" through a parser function. It may still be necessary to define some lookup API so that VE/Parsoid can easily translate some arbitrary magic word etc like {{PAGEID}} or __NOEDITSECTION__ to its appropriate equivalent parser function in order to do the templatedata fetch -- although the magic word ID is probably already the primary key we need.

Change 819740 had a related patch set uploaded (by C. Scott Ananian; author: C. Scott Ananian):

[mediawiki/extensions/TemplateData@master] Specification.md: Update to add parser functions and extension tags

https://gerrit.wikimedia.org/r/819740

The current specification uses dispatch: true on a parameter type to indicate an additional level of dynamic dispatch, which would be used for {{#tag}} and {{#invoke}}. I think this is where an additional hook would be invoked, TemplateDataDispatch with the value of the dispatch fields, with the default hook listener (aka fallback if no one else claims the particular hook invocation) being another message look up. Ie we look up templatedata-pf-tag to get a <templatedata> which has dispatch:true on the first parameter, then that will invoke TemplateDataDispatch(['#tag','syntaxhighlight']) to fetch more TemplateData, and if that returns null then it will look up templatedata-pf-tag-syntaxhighlight.

Note:

  1. The TemplateDataDispatch method takes an array of string parameters to the parser function (in the same way that the default calling convention for parser functions stringifies the arguments). If the parameters contain template invocations or are otherwise not-plain-strings, these arguments might be missing. You will get the "fallback" TemplateData in that case, and that's fine. To be explicit: if you write {{#invoke:{{my template}}|bar|bat}} you will probably get passed null in the arguments slot of TemplateDataDispatch and thus not get any "fancy" template data for this transclusion, you'll just get the generic template data for {{#invoke}}. That's ok; TemplateData is always optional. If you want precise and helpful template data, use plain strings in dispatch parameters.
  2. You can probably do without the TemplateDataDispatch hook in most cases, especially if you are willing to use transclusions in the message namespace. For example, the Scribunto 'foo' module might put {{:Module:Foo/doc}} in the templatedata-pf-invoke-foo message and then embed the template data in its doc page. You wouldn't *necessarily* need to write a TemplateDataDispatch hook. But I think TemplateDataDispatch provides some additional flexibility if (for example) you wanted to extract the template data from the comments of the lua module or do similar processing.
  3. You could probably provide (optional) arguments when you expand the templatedata-pf-invoke or templatedata-pf-invoke-foo message in the same way you pass them to TemplateDataDispatch and then use {{#if}} to redirect the templatedata request in interesting ways. I'm not sure that's /wise/, but it's another alternative to providing/implementing an explicit TemplateDataDispatch hook.