Talk:Requests for comment/HTML templating library

Handlebars
I [ NRuiz (WMF)] want to propose Handlebars as a choice. I have used for years with great ease. Going through your requirements:
 * Both a PHP and JS implementation
 * Handlebars is a superset of mustache so a PHP mustache implementation will have similar syntax to a client side implementation. I would not get to hang up in sharing templates server and client side, though. But if wanted templates in both instances differ little so having Handlebars client side and Mustache server side would work. To be fair I think we would find Mustache's lack of control ifs very hard to work with server side NRuiz (WMF) (talk) 22:45, 20 January 2014 (UTC)
 * I like handlebars. Which PHP implementation do you recommend, handlebars.php or lightncandy? -- S Page (WMF) (talk) 19:36, 23 January 2014 (UTC)

Handlebars syntax has these and several other handy loop constructs. See: http://handlebarsjs.com/ NRuiz (WMF) (talk) 22:45, 20 January 2014 (UTC)
 * if/else. array handling/detect an empty array

Handlebars escapes by default, you need special syntax to tell it not to escape.NRuiz (WMF) (talk) 22:45, 20 January 2014 (UTC)
 * Secure by default
 * Attribute sanitization (no XSS in href,)
 * You can easily write a Handlebars helper that creates links that looks like the following:

  
 * Parameter parsing can be taylored to our needs. Handlebars helpers are really extensible]
 * This makes manual escaping slightly more convenient, but does not make it automatic. This means that it is easy to forget escaping. It will be necessary to manually audit all templates for proper escaping for the given DOM context. -- Gabriel Wicke (GWicke) (talk) 00:06, 22 January 2014 (UTC)


 * Extensible enough to accommodate MediaWiki i18n system
 * Easy enough to provide a handlebars helper that can extract client side tokens (with runtime replacemants) from whatever localization system.
 * I have used handlebars with a javascript gettext implementation (http://jsgettext.berlios.de/) before but this localization system would be even better: http://slexaxton.github.io/Jed/
 * A handlebars helper for localization will look like:

 Handlebars.registerHelper('translate', function(domain, token) {       var args = Array.prototype.slice.call(arguments);         //remove options {} that handlebars passes at the end everytime        args.pop;        var t = I18N.translate.apply(I18N,args);        return new Handlebars.SafeString(t); }); 
 * You would use it like the following in the template engine:

   


 * Handlebars helpers are easy to use and give great flexibility. NRuiz (WMF) (talk) 22:45, 20 January 2014 (UTC)


 * No huge client-side footprint
 * Handlebars templates can be precompiled in node easily (this is crucial for performance).
 * Which reduces the complexity of working with partials and the footprint of templates. As they pass from html to a big function in javascript that just concatenates strings.NRuiz (WMF) (talk) 22:48, 20 January 2014 (UTC)
 * The lightncandy handlebars implementation in PHP supports compilation, it claims "10~30 times faster than https://github.com/XaminProject/handlebars.php". Also, after compiling you can call   to "Know required data structure from your templates. Verify input data, or find out missing variables with any jsonSchema validator". Intriguing... -- S Page (WMF) (talk) 20:48, 23 January 2014 (UTC)


 * Dumb (the less logic the better). Some template languages, for example jinja2 have a concept of filters where computation happens in the template itself. In my opinion this is unnecessary and can lead to complicated unreadable templates. Data should be preprocessed in PHP before being passed to a template.
 * Much agree. Template engine should only deal with links and localization, rest should be flat data.NRuiz (WMF) (talk) 22:48, 20 January 2014 (UTC)


 * Readable - templates should be easy to grasp for someone with basic HTML knowledge. Ideally they are just plain HTML with attributes, so that they can be displayed and edited with HTML tools (think VE). This can enable server-side pre-expansion followed by client-side updates.
 * Handlebars templates are simply HTML until compiled. NRuiz (WMF) (talk) 22:45, 20 January 2014 (UTC)
 * Handlebars uses curly braces, which are not HTML. The scope of curly brace blocks also does not need to align with DOM structures. -- Gabriel Wicke (GWicke) (talk) 00:09, 22 January 2014 (UTC)

Existing PHP templating in core
You might want to compare templates' PHP functioning to existing PHP solutions in Mediawiki core, like QuickTemplate. AndrewRussellGreen (talk) 02:52, 19 December 2013 (UTC)

I18n
I was very happy about mustache when I tried it out in one MediaWiki extension. For frontend it is pretty easy to include i18n support by using data-i18n attributes and jquery.i18n (though message loading is still not in core (nor is template loading yet)), but haven't figured how to do i18n in PHP. --Nikerabbit (talk) 12:17, 27 December 2013 (UTC)

Beyond templating
I have this feeling that AngularJS like stuff with controller bindings to the DOM etc is going to be next years thing. Have we considered/looked into this and what it means for templating ? I think it is too early for that right now perhaps, as far as I know there are no winners yet when it comes to MVW + template bindings as a combination. I just wanted to throw it out there and make sure that it was on people's radar before we pick a template engine. TheDJ (talk) 13:51, 4 January 2014 (UTC)


 * +1 on raising this aspect. Dynamic forms with client-side validation and help are another example where something like AngularJS might be helpful. -- Gabriel Wicke (GWicke) (talk) 19:59, 9 January 2014 (UTC)
 * Sorry but I disagree, templating itself is a problem that should not be coupled with a client side framework, several client side frameworks can work with any kind of templating engine. There is much benefit from being able to render client side without having to use per se a client side framework which might be too much of a big step.NRuiz (WMF) (talk) 22:17, 20 January 2014 (UTC)
 * I agree that we don't necessarily need reactive updates, so in that sense AngularJS is doing more than we need. It is possible to not use that functionality though.
 * With very simple string-based libraries like handlebars we'd end up writing our own framework. Security is an issue at best as a string-based library has no knowledge about the DOM and thus cannot guarantee proper escaping of attributes. This leads to more time spent on security reviews and a higher potential for security bugs. To me the main things simple libraries like mustache / handlebars have going for it are a) the ability to template non-HTML content, and b) simplicity and client-side size. -- Gabriel Wicke (GWicke) (talk) 22:13, 21 January 2014 (UTC)

Other aspects to consider
Some aspects that I am missing somewhat in this RFC:


 * form handling and -validation and its interaction with the template library
 * I think we should decouple the two problems (rendering and form parsing).The basic use case for templating is just rendering data that gets to the client as JSON, quite different from parsing user input in a form NRuiz (WMF)


 * systematic user content sanitization in DOM context
 * user sanitization (i.e. escaping) is done by Handlebars for example by default. (talk) 22:16, 20 January 2014 (UTC)

In the longer term, there could be overlap with content HTML templating as planned in Parsoid. Some extra and possibly differing requirements there are:


 * Visual editing: should support visual editing (so no magic syntax in templates, only HTML, simplicity)
 * Encourage data abstraction: access to JSON data sources and data-generating code modules instead of templated data in page content
 * Performance:
 * scoped variable definitions for efficient re-rendering of dynamic parts
 * integration with caching (dependency tracking, purges, incremental fragment updates)
 * Security: no infinite loops (only iteration), no unsanitized content injection

Overall it is not clear that the same solution can work well for HTML templating in both content and UI. There is no reason for this RFC to block on the Parsoid work, but it might be useful to keep content templating in mind. -- Gabriel Wicke (GWicke) (talk) 23:10, 7 January 2014 (UTC)

Feedback and next steps
See the 21 Feb 2014 meeting summary for steps that are currently underway. The PHP port is not done yet. As for Knockout, see Talk:Requests for comment/HTML templating library/Knockout - Tassembly for discussion of current work. Gabriel Wicke and others have been discussing the Flow use case with other Features engineers, and are tweaking the implementation in consultation with users. Sharihareswara (WMF) (talk) 22:08, 10 March 2014 (UTC)

port the JS IR compiler / runtime to PHP
This was one of the action items (the main one, repeated three times): was it done? --Nemo 09:22, 22 April 2014 (UTC)

Drupal-like templates
All of these template generators like Twig or Blade do not allow easy manipulation of previously generated output, which is possible with DOM. However DOM is a bit slow and too verbose. Anything that is manipulating html directly is too verbose. But there's middle approach. Let's take XSL, where one XML template tag could be mapped to the whole subtree of generated HTML tags (nodes). Such templates are powerful, can be processed in different ways and are not too verbose (not too low-level). Similar approach is used by Drupal 7 for years (so-called render arrays): $page = array( '#show_messages' => TRUE,  '#theme' => 'page',  '#type' => 'page',  'content' => array( 'system_main' => array(...), 'another_block' => array(...), '#sorted' => TRUE, ), 'sidebar_first' => array( ... ),  'footer' => array( ... ),  ... ); Imagine such templates, where associative array keys are view method names while array values are their parameters. These are powerful, not too verbose and can be altered multiple times in code until final output is produced. I sent a message about this to wikitech-l, however it didn't appear maybe due to being considered a spam. QuestPC (talk) 06:36, 20 March 2014 (UTC)
 * https://drupal.org/node/930760