By Jordan Boesch
Autobiography
- I'm a front-end developer for VendAsta
- I write a bunch of little jQuery plugins to give back to the community
www.boedesign.com - When I eat toast in the morning, my spread of choice is JavaScript
-
Some of my own side projects are:
What is JavaScript templating?
The ability to render HTML and replace content with data created by JavaScript.
Why?
Because doing this gets hairy...
// Make an ajax post to add a user
$.post('json/add_person.json', { person: 'bob', age: 55 }, function(data){
// Make an HTML template on the fly and add user data to it
var person_html = '<div id="person-' + data.user.id + '" class="person">';
person_html += '<h3>Example</h3><strong>' + data.user.name + '</strong>';
// If we find that this user has some children, we need to add them to the HTML output
if(data.user.children && data.user.children.length){
$.each(data.user.children, function(i, o){
person_html += '<div class="child">' + o.child_name + '</div>';
})
}
person_html += ' <span>' + data.user.age + '</span></div>';
// With the HTML template we just created, append it to the people list
$('#people').append(person_html);
}, 'json');
No worries!
There are solutions out there to make your JavaScript code less hairy.
"Oh plz dont take away my hair!" -Harry J. Script
Some popular libraries
-
jQuery Tmpl Plugin (6k minified)
http://api.jquery.com/jquery.tmpl/ -
Mustache JS (8k minified)
http://github.com/janl/mustache.js/ -
Underscore (8k minified)
http://documentcloud.github.com/underscore/
jQuery tmpl
The most common function
$.tmpl(template, data);
template: The HTML markup or text to use as a template.
data: The data to render. This can be any JavaScript type, including Array or Object.
jQuery tmpl example
Let's dive head-first into the code
Simple example
// First include the jQuery tmpl plugin
// OMG Microsoft is doing something open source?!
<script src="http://ajax.microsoft.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js"></script>
<script type="text/javascript">
var html_template = "<li>${name}</li>";
var new_tmpl = $.tmpl(html_template, { name: 'jimbo' });
alert(new_tmpl); // outputs <li>jimbo</li>
</script>
...Cool, but what if I don't want to store my HTML template in JavaScript?
How 'bout these apples?
Storing the template in HTML
// The browser has no idea how to render this script type.. perfect for sneaking templates in :D
<script id="person-tmpl" type="text/x-jquery-tmpl">
<div id="person-${user.id}" class="person">
<h3>Example</h3>
<strong>${user.name}</strong>
{{each(i, c) user.children}}
<div class="child">${c.child_name}</div>
{{/each}}
<span>${user.age}</span>
</div>
</script>
<script type="text/javascript">
// Shortcut for $(document).ready
$(function(){
$.post('json/add_person.json', { person: 'bob', age: 55 }, function(data){
$.tmpl($('#person-tmpl'), data).appendTo('#people');
}, 'json');
});
</script>
Conditional logic
<script id="person-tmpl" type="text/x-jquery-tmpl">
<div id="person-${user.id}" class="person">
<h3>Example</h3>
{{if user.name}}
<strong>${user.name}</strong>
{{else}}
<strong>No name found</strong>
{{/if}}
{{each(i, c) user.children}}
<div class="child">${c.child_name}</div>
{{/each}}
<span>${user.age}</span>
</div>
</script>
Caching
Re-querying the DOM each time isn't always necessary
$.template(name, template)
name: A string naming the compiled template.
template: The HTML markup and/or text to be used as template. Can be a string, or an HTML element (or jQuery object wrapping an element) whose content is to be used as template.
Caching
<script id="person-tmpl" type="text/x-jquery-tmpl">
<div id="person-${user.id}" class="person">
<h3>Example</h3>
<strong>${user.name}</strong>
{{each(i, c) user.children}}
<div class="child">${c.child_name}</div>
{{/each}}
<span>${user.age}</span>
</div>
</script>
<script type="text/javascript">
// Shortcut for $(document).ready
$(function(){
// Store the template with a keyname and use it later
$.template('person-template', $('#person-tmpl'));
$.post('json/add_person.json', { person: 'bob', age: 55 }, function(data){
$.tmpl('person-template', data).appendTo('#people');
}, 'json');
});
</script>
Caching
So how much quicker is it?
<script type="text/javascript">
$.template('person-template', $('#person-tmpl'));
// Run this 1000 times (288ms)
$.tmpl('person-template', data);
// Run this 1000 times (676ms)
$.tmpl($('#person-tmpl'), data);
</script>
A known issue with jQuery tmpl
Use django? The jQuery tmpl {{ }} braces conflict with django template tags!
Issue logged here: http://github.com/nje/jquery-tmpl/issues#issue/17
This breaks...
<script type="text/x-jquery-tmpl">
{{each(i, c) user.children}}
<div class="child">${c.child_name}</div>
{{/each}}
</script>
This is "hacky" but it won't break...
<script type="text/x-jquery-tmpl">
[[each(i, c) user.children]]
<div class="child">${c.child_name}</div>
[[/each]]
</script>
<script type="text/javascript">
$(function(){
// Go find any script template blocks
// and replace [[ with {{ and ]] with }}
$("script").each(function(){
var new_replaced_txt = $(this).text().replace(/\[\[/g, "{{").replace(/\]\]/g, "}}");
$(this).text(new_replaced_txt);
});
// Ok we've dodged django, now we're ready to call $.tmpl on our code.
});
</script>
Support for browsers with JavaScript disabled?
HELL NO! SCREW 'EM!... but not really.
If you're wanting to support that 2% of people that have JavaScript disabled, Mustache JS might be a better alternative - sorry for wasting your time ;)
http://mustache.github.com/
Available in Ruby, JavaScript, Python, Erlang, PHP, Perl, Go, Lua, ooc, C++, ActionScript, Java, ColdFusion, Scala, and for node.js.
Benchmark of a tonne of JS Templating plugins
Thanks for letting me steal your stat 'n shit. K THX BI.
http://www.viget.com/extend/benchmarking-javascript-templating-libraries/
FIN
Please place your 3D glasses in the box beside the door on your way out.
http://www.twitter.com/jboesch
http://www.boedesign.com
http://www.github.com/jboesch