Template Object Model

Lets flesh out a basic HTML DOM templating interface here.

Requirements

 * Both a PHP and JS implementation
 * Resource loader needs to support loading templates
 * thoughts on speculative loading
 * also elements in HTML5
 * tendency to move towards JS for client side (and later server-side) templating
 * if/else
 * array handling
 * foreach
 * detect an empty array
 * Template partials / transclusion
 * Ability to control HTML escaping (preferably with escaped output as the default)
 * Should be obvious to see what is escaped by looking at the template
 * Context sensitive escaping (attributes)
 * Extensible enough to accommodate MediaWiki i18n system
 * Should either be a custom implementation of the library or a predefined function/filter
 * Ensures balanced templates (partial DOM)
 * Client-side library that has a small footprint (~20K or less)
 * should support visual editing (so no magic syntax in templates, only HTML, simplicity)

Interesting implementations

 * Distal -- Zope TAL in JS
 * Genshi -- cleaner than TAL, very close to what we are looking for, but Python implementation rather than JS
 * AngularJS -- attribute-based HTML templates compiled to code (?), reactive programming with separate model
 * React -- compiles HTML templates to efficient code, reactive
 * XHP -- FB XML literals in PHP; slow in Wikia testing, PHP only.

Spec strawman
In uncompiled templates, we can use user-friendly and compact syntax similar to mustache :

Transclusion can be defined with this syntax:

This calls the template 'link' via a possible 'link' controller. The 'link' template:

For visual editing, this can be de-sugared to a pure XHTML+RDFa template by replacing the brace syntax with elements and attributes suitable for visual editing:

Expressions

 * data references in dot and [] notation:  and   or
 * iteration in : ,   var, but does not provide access to nested enumeration counters. Maybe something like   and   for objects?
 * arithmetic:
 * (in)equality predicates:
 * logical negation/and/or, parenthesis:

We considered also supporting function calls, but decided to go with data references only for now to keep porting straightforward, and maintain a clear separation between formatting options and data. If necessary, such support can be added at a later point.

Possible things to add to expressions
Things that could be useful in expressions as they are a property of a view rather than the model. This is mainly about things that can be used in conditionals and iteration specifications. Localized formatting (numbers, uppercase, plural etc) can be handled with properties. We don't implement these straight away to keep porting simple, but could consider adding these features later.
 * length of arrays, maybe  or   -- to print the length, change layout depending on length
 * slicing on arrays -- Python syntax?  -- to split up a long array in the view or only display the top n entries
 * calls of functions in the controller: can be used to implement more complex predicates, sorting etc
 * plain data access maps to the model, functions to the controller?
 * more math, as in the JS Math module contents?
 * could also be left to the controller

Things probably better implemented in the controller are
 * default sorting: complex, JS can re-sort client-side
 * should have access to locale in scope

Value formatting
Via attributes on the  element. I18n behavior inherited by DOM scope.


 * Strings
 * maxlength
 * case= upper/lower
 * Numbers
 * fmt format string (precision, padding etc)

Escaping
By default, escape everything as user input depending on context:
 * To text in text content
 * Per-attribute sanitization for all templated attribute values (href, src, style etc) after full expansion

The provenance of data is a property of the data, so we require any data that is not to be treated as user-supplied unsafe data to document this by encapsulating the data in an object:

Higher-level widgets
Basically like extensions.


 * Declarative with freedom of implementation
 * Rich support in VE possible
 * Drop-downs of options
 * Data type driven formatting (date/birthday formatted as localized age)
 * In-place editing of the underlying data within the rendering
 * Table widget alternative to data tables with table start / row / end templates
 * Both table and plot could come in handy in special pages

Prototype
We'll probably develop a  prototype over the weekend, likely based on distal.