JavaScript Template Libraries

Adding content to a page is a staple activity in an Ajax browser application and I've seen many JavaScript templating libraries for generating the HTML to be added. Overall I think this is a bad practice and avoidable.

Example

The TrimPath templates are one of the older examples of using template to generate HTML in the browser. Here is a 1 minute version of the TrimPath 10 minute Introduction

Somehow there needs to be some data available to the JavaScript. This data could be written into the page by the server-side tempting engine or could be the server response for an Ajax request. Here is some data written into the page.

<script language="javascript">
    var data = {people:[{first:'Fred', last:'Flintstone'},
                        {first:'Barney', last:'Rubble'}]};
</script>

The templates that convert this data into bits of HTML are commonly stored in hidden elements in the page.

<textarea id="people_jst" style="display:none;">
  {for p in people}
    <li>{p.first} {p.last}</li>
  {/for}
</textarea>

Then generate the HTML from the data and template.

<script language="javascript">
    var result = TrimPath.processDOMTemplate("people_jst", data);
    document.getElementById('list').innerHTML = result;
</script>

Cons

For the standaristas, this templating approach is not semantic. The content of the hidden text area is not part of the page content: it is part of the page's behavior because it is for the sole use of the JavaScript. Storing the template in a hidden element in the page would be enough to give a standards purest a perforated ulcer. I'm definitely with them on this one.

Using a templating system in the browser requires the template processing library to be downloaded to the browser. The TrimPath libary is 10496 bytes minimized or 3119 bytes minimized and gzipped. This is not huge overhead but adding several unnecessary 3 KB libraries to a page definitely starts to add up when there are also the usual event and Ajax libraries included too. There is also the cost of any bugs that may be present in the 400 lines of template library code. Even though the TrimPath templating library isn't too big it likely would grow as people add more features.

For me there just seems to be and associated stench from burdening the browser with parsing and processing templates each time they are used. In JavaScript we can write the above template as.

function people_jst(data) {
  var html = '';
  for (var i=0; i<data.people.length; i++) {
    var p = data.people[i];
    html += '<li>'+p.first+' '+p.last+'</li>';
  }
  return html;
}

No this JavaScript function isn't as pretty as the template and isn't as easy to maintain as the template complexity grows. It is much easier and safer to have a designer work on templates then on JavaScript functions. Developers are accustomed to the nice embedded HTML templates on the server-side and it is natural to want the same on the client-side.

Pros

There is only one real pro I can think of for sending a template to the browser like TrimPath and many other libraries use. If the template is used server-side then it can be shared with the client side. This is DRY and therefore good, however there is at least one other way to stay DRY in this situation.

Send Compiled Templates to the Browser

Instead of a client-side templating library to process templates repeatedly, as needed, we can have a server-side template library that compiles our templates into JavaScript functions like I have done manually above. These JavaScript functions are then sent to the browser. By doing this we are DRY, have reduced browser library dependency, improved browser performance and we can work on templates to develop our HTML.

In Rails, for example, DRY is one of the most important tenets. To stay DRY, Ajax is used to call the server to render little bits of HTML that are then dynamically inserted into the page. With the ability to share templates easily with the JavaScript as compiled functions, this client-server chatter would be reduced. If the embedded templating language is JavaScript then the template to function conversion would be trivial. Using JavaScript on the server-side is not standard now but it won't be long until it is.

Comments

Have something to write? Comment on this article.

Andrew Hedges July 7, 2007

Interesting post, Peter. I'm surprised you don't mention Prototype's Template object. Of course, it's overhead to include Prototype, but if you're including it anyway, it seems like a great way to let designers markup templates in the way most natural to them and let JavaScript fill in the values.

Andy Wardley July 9, 2007

You might want to have a look at Jemplate

http://search.cpan.org/~ingy/Jemplate-0.20/lib/Jemplate.pm

Denis August 16, 2007

Peter, have not we been here with all the JSP stuff? The suggested approach has exactly all the downsides of JSPs, namely mixing of presentation and logic, but on the client side and with JavaScript. You cannot really give that template to a web designer (i.e. an artist who knows HTML/CSS but does not understand JavaScript) and expect him/her to author that template. IMHO, the right way to go is "The Tapestry Way", when a template does not have any code, but being interpreted and rendered by a special engine. This approach is implemented in Dojo and other frameworks (jGrouse being one of them).

Peter Michaux August 16, 2007

Denis,

Different templating engines mix in differing levels of logic. Even Tapestry isn't simply HTML and CSS that a designer of non-dynamic pages would know. There is code masquerading the form of special element attributes and mysterious Java values. Regardless, you could use any templating system you like for authoring the pages. The options I am looking at here are what is sent to the browser. Should the development templates and the rendering engine be sent to the browser or should the template be automatically compiled to JavaScript on the server-side so that the engine isn't needed on the client-side? The latter option becomes more appealing as the templating system/engine grows in complexity.

Steve Yen August 16, 2007

Peter, I like this precompiling idea, so on it goes to the todo list for TrimPath Junction, since Junction allows for both server-side and client-side template rendering.

Chris Anderson October 31, 2007

On Grabb.it, we tend to mostly serve static JSON files, and do all the rendering as Javascript functions in the browser. When it comes time to render HTML versions of the views, for Google and old old browsers, I usually just end up rewriting the Javascript functions as erb templates.

For me the way to go DRY would be running the original Javascript on the server, against the same JSON data, and serving the results as HTML.

Peter Michaux October 31, 2007

Chris,

Your conclusion for how to stay DRY is exactly why I think JavaScript should be running on the server. More people will agree as time goes on and there is larger investment in code that must be written in JavaScript for the client-side.

Sam Elsamman December 5, 2007

I recently decided to test a client-centric design pattern on a project we did for a client. Both the view and the controller were entirely in the browser with only the model (via a services-oriented API using JSON) on the server.

We used Jemplate for the templating. You don't need to use Perl at all with Jemplate even though it is based on the Perl Template Toolkit. Jemplate pre-compiles the templates into JS and merges in the data in the browser like Trimpath.

I was surprised to find that the application was very easy to structure and to maintain. Because it caches data it is quite fast with minimum server chatter. I will certainly try similar patterns in future applications.

Justin Meyer February 17, 2008

Check out EJS for a very complete, lightweight JavaScript templating library. It's basically eRB rewritten in JavaScript. But it includes a few other nice features and has easy to use syntax.

It's also got a compiler page that turns your templates into functions.

MoXie September 23, 2008

http://code.google.com/p/jssmarty/

Another javascript template engine :)

Chris Esler November 13, 2008

Peter,

I've been using Tenjin in my rhimoo server code, and it works pretty good.

http://www.kuwata-lab.com/tenjin/

Chris

Mic December 15, 2008

Hi Peter,

You can have a look at PURE: http://beebole.com/pure/ Or download some quick examples from http://github.com/pure/pure/downloads/master

PURE is unobtrusive, the HTML is kept intact. No tags or code break it.

The HTML is compiled in JS functions for a very fast rendering. These functions can then be collected to a JS file for production use.

Cheers

Have something to write? Comment on this article.