Dearest Gaia Developers,
Pleased to announce that we've moved the templating mechanism that was
developed for Messages app to shared/js. Tests can be found and executed
from system/test/unit/template_test.js.
Several months ago, Julien Wajsberg (:julienw) and I worked together to
move all of the markup strings out of the Messages application program code
and into string templates that could be stored in the application's
index.html. In this effort, we developed a very simple but very useful
string interpolation mechanism that effectively solved all of our
templating needs while abiding the restrictions of FirefoxOS's Content
Security Policy. As Bocoup expanded our attention to the Clock app, we
realized that the same needs existed there. The solution was to move the
Template code out of Messages and into shared/js; through coordination with
peers in Clock, Messages and "shared/js", we've successfully moved the code
today.
Using the Template library is simple:
1. Add <script src="shared/js/template.js"></script> to your index.html
2. Create your template as a comment node inside of any type of element,
place in index.html:
<span id="emphasis-template">
<!-- <${tag}>${value}</${tag}> -->
</span>
<span id="greeting-template">
<!-- Hello ${name}! -->
</span>
3. In your JavaScript code, initialize an instance of this template:
// Template will accept either an id string or a node!
var emphasis = new Template('emphasis-template');
var greeting = new Template(document.getElementById('greeting-template'));
4. Generate a safe markup string with specified values by calling the
`interpolate` method of the template object:
greeting.interpolate({
name: 'World'
});
// Hello World!
Simple partial nesting is supported, just tell `interpolate` which
properties are "safe":
var name = emphasis.interpolate({
tag: 'b',
value: 'World'
});
// we know that the value of 'name' has already been escaped :)
greeting.interpolate({ name: name }, { safe: ['name'] });
// Hello <b>World</b>!
Markup strings produced by Template are innerHTML safe (unless explicitly
marked otherwise, as shown above):
greeting.interpolate({
name: '<script>alert("hi!")' + '</script>'
});
// <script>alert("hi!")</script>
Template instances disallow modification of the template string once the
object is initialized, but the toString() method will return the raw
template as a string:
greeting.toString();
// Hello ${name}!
emphasis.toString();
// <${tag}>${value}</${tag}>
It's important to remember that Template and WebComponent are not at odds
with each other and exist to serve to different purposes; read more here:
https://bugzilla.mozilla.org/show_bug.cgi?id=908950#c6
Finally, we're exploring the addition of two methods that will allow a
program to specify a dom element or document fragment as an insertion
target for the interpolated string output. If you know of any other
general-purpose functionality that might be helpful, please let me know!
Rick