arraysize: 0


TemplateFunc extension

The TemplateFunc extension is designed to offer new ways of fetching data from wiki pages and converting them to other data formats for use in the wiki, including wiki template markup, JSON, Mustache templates and Smarty widgets. It was specifically created to work with multiple-instance templates and to offer solutions to issues that are expected to arise in the future as Parsoid takes over as the de facto MediaWiki parser.
Extension

Parser functions

(1) #tf-convert

To fetch and move around structured data, this parser function goes through the following steps:

  • It reads data from the intended wiki page, provided that it holds data using either a wiki template or a JSON string.
  • Internally, it transforms the data to an array in PHP.
  • Finally, it assigns data to one of the supported output formats below.

In addition, this parser function also lets you fetch the raw, unprocessed content of a wiki page.

Syntax

Example, with comments:

{{#tf-convert:
|page={{FULLPAGENAME}}
|slot=Optional. Name of the content slot (default: "main")
|sourceformat= // template (default) or json
|sourcenode= // used if sourceformat=json. If empty, the root node will be used instead.
|sourcetemplate=Recipe[Ingredients].Ingredient // used if sourceformat=template, here meaning instances of Template:Ingredient that are added to the Ingredients parameter of Template:Recipe

  // or use three parameters, though this may not be supported in the future:
  |parenttemplate=Recipe
  |parenttemplateparam=Ingredients
  |template=Ingredient

// Choose only one of the following targets:
|targettemplate=Ingredient subobject // The wiki template to be used
|targetwidget= // The widget to be used
|targetmodule= // The Lua module to be used
|targetmustache= //
  |targetmustachedir= // Mustache directory if targetmustache is used
|target= // can be set to raw

// Map parameter names from source to target:
|data=What=Item, How much=Mass, How many=Quantity // Map the parameter names of the source code to parameters of the target. Use data=all (default) to map all parameters verbatim. It is similar to the parameter of the same name in ExternalData's #get_web_data

// Additional parameters to pass to the target:
|indexname=index // how to name the index. Simply defaults to: index
|userparam1= custom user parameter (optional). Custom parameters must begin with 'userparam'. What follows is up to you.
|userparam2= another custom parameter (optional)
|userparam3= etc.

|mode= // See note on lazy mode below.
}}
Supported input formats
  • Wiki template markup
  • JSON - Sometimes you may want to store data in a more universal format like JSON, which allows for interoperability with functionality written in PHP and JavaScript.
Supported output formats
  • Wiki template markup
  • JSON - currently just a representation. Would there be any interest in downloadable files?
  • Mustache, using MediaWiki's templating engine for Mustache.
  • Output to parser functions
    • #widget as provided by the Widgets extension, which is based on Smarty
    • Lua/Scribunto's #invoke

  • (2) #tf-mustache

    A standalone parser function that lets you use Mustache templates on the server.


    Purposes

    Tackling Parsoid

    Wiki templates are by themselves agnostic of the context in which they are used. If a template requires data from the wiki page on which it appears, data that is not part of any user input, it can make use of magic words like FULLPAGENAME and maybe a semantic query, but if the same template is used multiple times in a row, this approach is not terribly efficient. An instance of a template within such a sequence also has no way knowing its position. Does it come first, second, last?

    In the days before Parsoid, variable-like constructs of global scope allowed me to throw around data where I needed them much more easily :

    • Transfer data from a parent template to its child templates.
    • Transfer data from a multiple-instance template to the next one in a series of such instances. A simple example would be to create a counter so that SMW's subobjects can store a sortable key by which they can be queried.

    These solutions will no longer be possible by the time Parsoid has definitively replaced the legacy parser, as described elsewhere on this site. The idea of the #tf-convert parser function is that it solves the problem by reading the raw, unprocessed source code from the page, sending additional data to each template if necessary, assigning all data to a new template or another output format, and sending everything to the parser for the final step in processing.

    Reading source data from another page

    The parser function can read data from another wiki page.

    A particular application of this feature that I found useful is to embed content from other pages and through the use of user parameters, to change the templates' behaviour in their new context, such as telling them not use SMW's subobjects.

    JSON as a source format

    Thanks in no small part to extensions like Page Forms and Semantic MediaWiki, the direct use of wiki templates as data carriers has a long, almost venerable tradition in the history of MediaWiki and third-party development. Because the resulting syntax structure, including the use of multiple-instance templates, has little support beyond MediaWiki, it would not be terribly suitable as a data interchange format if that is what you happen to be looking for. Perhaps you prefer a stricter separation of data and presentatipn. Whatever the case may be, JSON would be a good fit as an alternative. Recent years have seen wider support as well as wider adoption of JSON as a means of holding structured data. MediaWiki itself supports JSON as a content model for wiki pages, including content slots, and extensions like FlexForm, WSSlots and External Data are essential tools for working with JSON data.

    Like WSSlots' #slotdata and ExternalData's #get_web_data, this parser function lets you use data written in JSON. The data can be 'fed' to a wiki template, or a widget, etc.


    Examples

    The general approach is to read the raw source code, extract the templates and internally convert them to arrays so that data can be flexibly reassigned to a different or enhanced format.

    Template to template

    Imagine our wiki page has the following structure consisting of a parent template (Recipe) and nested instances of a child template (Ingredient):

    {{Recipe
    |Name=Grilled Zucchini and Yellow Squash with Champagne Vinaigrette
    |Ingredients={{Ingredient
     |Name=Olive oil
     |Quantity=2 tablespoons
    }}{{Ingredient
     |Name=Zucchini
     |Quantity=4 medium ones, halved
    }}{{Ingredient
     |Name=Squash
     |Quantity=3 medium ones, halved
    }}{{Ingredient
     |Name=Champagne Vinaigrette
     |Quantity=Don't overdo it
     }}
    }}
    

    Part of the Recipe template is another template called Ingredient subobject that takes care of the semantic properties using a subobject. It should receive user-provided data from the Ingredient template along with the index number, 'fullpagename' and a general comment that should apply to each ingredient. We also need to map the arguments because the Ingredient subobject template was created using different parameter names, "what" and "how much".

    To achieve this, we could add something like this to the Recipe template:

    {{#tf-convert:
    |page={{FULLPAGENAME}}
    |sourcetemplate=Recipe[Ingredients].Ingredient
    |targettemplate=Ingredient subobject
    |data=Name=what,Quantity=how much
    |indexname=index
    |userparam1={{{Comment|}}}
    }}
    Which would print something like:
    {{Ingredient subobject
    |index=1
    |fullpagename=Show:Lab/TemplateFunc
    |what=Olive oil
    |how much==2 tablespoons
    |userparam1=On the shopping list // Supposing this is our comment
    }}{{Ingredient subobject
    |index=2
    ...
    |userparam1=Shopping required
    }}
    etc.


    Template to widget

    Similarly, if we were to draw the same data from the present page but (a) we do so on another wiki page, (b) use a widget called Ingredient, and (c) set the colour of this widget to green, we could write :

    {{#tf-convert:
    |page=Show:Lab/TemplateFunc
    |sourcetemplate=Recipe[Ingredients].Ingredient
    |targetwidget=Ingredient
    |data=all // assuming this time the parameters are identically named
    |indexname=index
    |userparam1=green
    }}

    JSON to wiki template

    The relevant parameters would be as follows:

    {{#tf-convert:
    |page=
    |slot=
    |sourceformat=json
    |sourcenode=
    |data=
    |targettemplate=
    }}

    Get the raw source code

    Say we have no need of data conversions. What we want instead is the ability to load all of the source code from a wiki page containing TEI XML in a form input. To achieve this, we can use this parser function with sourceformat set to "raw" as well as target set to "raw". For example:

    {{#tf-convert:
    |page=Cetei:...
    |sourceformat=raw
    |target=raw
    }}

    See here for further details

    Other features

    • When used with the CODECSResources extension, the parser function provides an experimental option to load content lazily. This is done by setting mode=lazy. It should not be expected to work when the generated content relies on processes, whether in JavaScript or PHP, that have already run before the content is generated.