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.
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.
**Notes**: the data context object for the template should incude the wikidata entity object (equivalent to `mw.wikibase.getEntityObject()`) by default, WLOG as a 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`).
**To do**: how do references to entities other than the one for the current page work? Can we embed SPARQL queries, or should this be delegated to the Scribunto module, not embedded in the arguments?