I recently had to do some really heavy lifting with templates in JavaScript, and opted to use John Resig’s “Micro-templating” within the Underscore.js Library. It’s nice, you can write JavaScript within your templates to control your flow, like:
It's been <%= (new Date()).getTime() %> milliseconds since the epoch.
Which, if you’re like me is great. You could use Google Closure Templates, which probably is faster, but then you would have to precompile your templates, which is a pain.
The only problem I personally had with the Resig solution was that if you tried to call a variable that didn’t exist within your data object, it would fail horrifically, so I modified it slightly to be slightly more forgiving:
// JavaScript templating a-la ERB, pilfered from John Resig's
// "Secrets of the JavaScript Ninja", page 83.
// Single-quote fix from Rick Strahl's version.
_.template = function(str, data) {
var fn = new Function('obj',
'var p=[],print=function(){p.push.apply(p,arguments);};' +
'with(obj){p.push(\'' +
str.replace(/[\r\t\n]/g, " ")
.replace(/'(?=[^%]*%>)/g,"\t")
.split("'").join("\\'")
.split("\t").join("'")
.replace(//g, "',(typeof($1)!='undefined') ? $1:'','") // modified to allow undefined variables pass through
.split("").join("p.push('")
+ "');}return p.join('');");
return data ? fn(data) : fn;
};
The 12th line where it says .replace(//g…) includes a test for the data that is being passed into the function that’s being created to output just an empty string if the variable is undefined.