We can use Visual Editor to edit templates, and in the process better separate code, content, and presentation. We're going to call these "Visual Templates".
Here are the [key ideas](https://wikimania2015.wikimedia.org/w/index.php?title=File%3ATemplates_are_dead!_Long_live_templates!.pdf&page=35):
# A minimal "logic-less" template language, like the [Spacebars](https://github.com/meteor/meteor/blob/devel/packages/spacebars/README.md) variant of [Handlebars](http://handlebarsjs.com/)/[mustache](https://mustache.github.io/) templates. There are only three basic template constructs (variable interpolation, block tags, and partials), which can all be visualized in the editor. There are no hidden directives.
# All logic is written in a real programming language, via [Scribunto](https://www.mediawiki.org/wiki/Extension:Scribunto). In the examples below I'll be using a version of Scribunto that supports JavaScript as well as Lua; forgive my eccentricities.
# All data is escaped and hygienic by default. String data is automatically escaped. The Scribunto code manipulates and returns [`DocumentFragment`s](https://developer.mozilla.org/en-US/docs/Web/API/DocumentFragment), not wikitext strings.
# Similarly, arguments are strings/numerical data, `DocumentFragment`s, or wikidata queries, not wikitext.
# Composition of content is structural, not string concatenation. You can't "accidentally" create a list item if your template result happens to start with a `:` or `*`.
So: every Visual Template is composed of two parts: a scribunto module (edited with a code editor), and a "layout" (edited with visual editor).
Here's what the layout of a particular template might look like:
{F2651938}
Forgive the terrible yellow; a designer could make this look much nicer. Note that there are two "block helper" invocations, `each` and `caption`. The `each` helper is a built-in, and its given `row` from the template data context object. The `caption` helper is defined by the scribunto module. Each row of the table gets "variable" invocations to fill in the table cells.
There are only three new functions added to the VE toolbar in template mode, for inserting "variable", "block helper", and "partial" elements. Context-sensitive help will be given for available variable, block helper, and partial names.
Here's what the scribunto module might look like:
{F2651945}
This uses JavaScript ES6 module syntax. The default entry point transforms the template arguments to set up the template data context. There is a second `caption` entry point, which defines the `caption` block helper.
The invocation of this template would, for this example, take structured data of the following form, perhaps from a wikidata query:
| event | gold | silver | bronze |
| Shotput | USA | GER | MEX |
| Discus | MEX | USA | GER |
| Javelin | GER | MEX | USA |
The scribunto module in this example transforms this raw data by computing medal counts for each country.
**To do**: Mock up what the template invocation site looks like in Visual Editor**Visual Template invocation in Visual Editor**
The primary authoring mechanism for Visual Templates is expected to be Visual Editor. The UX is expected to be roughly the same as exists now for templates: a mechanism like TemplateData exposes the expected types of arguments and descriptive text, so that Visual Editor can expose appropriate editing widgets. Initially the expected types are: "markup" (edited with VE recursively), JSON (edited with a JSON editor, as with TemplateData), and "wikidata" (a SPARQL wikidata query).
**Visual Template Invocation in wikitext**
This is a strawman for the wikitext serialization of a template invocation:
```
{{#visual
template_name
param1=<markup>'''bold'''</markup>
param2=<json>{"foo":"bar"}</json>
param3=<wikidata>
SELECT ?spaceProbeLabel ?date ?picture
WHERE {
?spaceProbe wdt:P31 wd:Q26529 ;
wdt:P18 ?picture ;
wdt:P619 ?date .
SERVICE wikibase:label {
bd:serviceParam wikibase:language "fr,en" .
}
}
ORDER BY ?date
</wikidata>
}}
```
The parameter name `entity` is reserved; the data context object for the template always includes the wikidata entity object (equivalent to `mw.wikibase.getEntityObject()`) as an implicit parameter named `entity`. This makes it extremely easy to generate infoboxes (for example), since you can just insert `{{#formatproperty entity.P17}}` in your template (equivalent to `entity.formatPropertyValues( 'P17' ).value`).
**Notes**: the data context object for the template should incude the wikidata entity object (equivalent to `mw.wikibase.getEntityObject()`) by default,Since arguments are delimited by html-style tags, the usual & WLOG as a parameter named `entity`. This makes it extremely easy to generate infoboxes (for example)and < escapes are all that are required to include arbitrary data inside a parameter, since you can just insert `{{#formatproperty|entity.P17}}` in your template (equivalent to `entity.formatPropertyValues( 'P17' ).value`)and whitespace can be used to separate arguments. The parameter names can be omitted for positional arguments.
**To do**: how do references to entities other than the one for the current page work? Can we embed SPARQL queries//Perhaps we can allow for an abbreivated format for certain arguments: `"..."` -> literal string, `\d+` -> number, or should this be delegated to the Scribunto module,`{...}` -> JSON value. not embedded in the arguments?Then unit conversion (for example) can still be simply `{{#visual convertToMiles 5 km}}`//