UnderscoreJS
Templates
UnderscoreJS uses a very simple but efficient template system, the basic syntax is:
_.template( html, args );
Where the html source contains place-holders using <% and %> delimieters containing the names of properties to be filled from the args object. The property names are preceded by =, - or nothing depending on whether your property is a normal expression, needs escaping, or is raw JavaScript. See this good tutorial for more detail.
If the _.template function is called without the second parameter, then it will return a compiled version of the template in the form of a function that can be called with arguments when needed.
The following is a method I use for lazy-loading the templates, it's called with three parameters. The first is the name of the template which will be loaded from the templates directory and appended with ".html", the second is the arguments, and the third is the target for the final HTML populated with the arguments, and can be either a function to pass the HTML to, or a jQuery selector string or element to set the HTML for. The first time a template is used it is loaded and compiled, and the callback is used to render an spinner icon while the template is first loading.
foo.template = function(template, args, target) {
// Function to do the final rendering once the html is populated with the args
function render(html, target) {
typeof target == 'function' ? target(html) : $(target).html(html);
}
// Create a list for the templates if not already existent
if(!('templates' in this)) this.templates = [];
// If the template is already loaded and compiled, process the final result immediately
if(template in this.templates) render(this.templates[template](args), target);
// Otherwise load the template, and when it's loaded compile it and return the result
else {
render('<div class="loading"></div>', target);
$.ajax({
type: 'GET',
url: '/templates/' + template + '.html',
context: this,
dataType: 'html',
success: function(html) {
// Compile the template
this.templates[template] = _.template(html);
// Process the template with our args and send through the callback
render(this.templates[template](args), target);
}
});
}
};