Javascript template engine

July 3, 2012

Did some research on what the most efficient way of creating nodes with javascript is, and to my surprise I found out that writing out html to the innerHTML of a parent object is more efficient than using document.createElement/appendChild. Which I think is wierd considering it should be more work for the DOMparser to parse through a string rather than appending objects.

Well anyway, I started thinking about an easy way of doing templating in javascript. I’ve always used the createElement/appendChild approach, but innerHTML is a lot easier to read than going through lots of javascript, especially¬†if the structure is somewhat advanced. And seeing that innerHTML is sometimes up to ~5 times faster than createElement/appendChild, the obvious choice is to start using the innerHTML way.
The biggest downside with innerHTML is that when building html, you lose track pretty fast when you have no highlighting on the strings that you work with.
E.g.

// Define username as beije
var username = 'beije';

// Define ouput as string
// Create a table with two columns, one with a static word and the other with a variable
var output = '<table><tbody><tr><td>Name:</td><td>'+username+'</td></tr></tbody></table>';

// Append data to an element
element.innerHTML = output;

Now visualize that the above table actually had five columns and 30 rows, the data would pretty quickly become hard to read.

This is my proposal, a template engine, where you write your HTML markup in individual HTML-files, which are then fetched with ajax and are rendered with javascript. I wrote this class yesterday night, so might be that I’ve missed something. But it supports nested templates, i.e. one template for the table structure and one for each row, which you then can render together.
As usual the source files that I give contain all the documentation for the different functions as well as how to use it.
Anyway, I’ll copy over some example code.

Javascript initialization & rendering example:

// Init templateengine, this should only be initialized once per page!
var tplengine = new Templateengine( '//benjaminhorn.io/data/jstemplateengine/', 'templates/' );

// Create object for our main template ('profile')
var profile = new Object();
profile['profileimage'] = 'gfx/profileimage.jpg';
profile['profileimagelink'] = 'This is my profile image';
profile['profilename'] = 'Beije';

// Create the variables for our sub template
// ( //benjaminhorn.io/data/jstemplateengine/templates/anchor.html )
var templatevars = new Array();
templatevars['link'] = '//benjaminhorn.io';
templatevars['title'] = 'Click on my link!';
templatevars['content'] = 'My link!';

// Lets nest the templates, rendering the subtemplate anchor
profile['profilelink'] = tplengine.rendertemplate( templatevars , 'anchor' );

var templatevars = new Object();
templatevars['content'] = '';

// Render subtemplate, profile, 10 times (If this was the real world, there would be 10 different profiles)
for( var n = 0; n < 10; n++ )
{
	templatevars['content'] += tplengine.rendertemplate( profile , 'profile' );
}

// Render final template, profile
document.body.innerHTML = tplengine.rendertemplate( templatevars , 'container' );

A HTML template:

<div class="profile-container">
	<img src="$profileimage" title="$profilimagetitle" class="image"/>
	<div class="description">
		<dl>
			<dt>
				Name:
			</dt>
			<dd>
				$profilename
			</dd>
			<dt>
				Website:
			</dt>
			<dd>
				$profilelink
			</dd>
		</dl>
	</div>
	<div class="clear"></div>
</div>

Here’s a live demo (The above example ^^)!

Download source code with example

[Update]
I noticed that my JS templater has a lot in common with mustache¬†(mine’s a lot simpler with probably less functions). But when I browsed through their source I noticed that they were caching the templates while mine loaded them every time the templateengine needed it, so I implemented a similar caching system as theirs.

Tags