Handlebars.js: The only good JavaScript template engine?

I wanted to figure out how I could turn the following object:

var Q = {'questions': [
    {
        'id': "Q1",
        'text': "Is this is a question?",
        'answers': [
            { 'id': "Q1A", 'text': "An answer" },
            { 'id': "Q1B", 'text': "Another answer" },
            { 'id': "Q1C", 'text': "One more answer" },
            { 'id': "Q1D", 'text': "Can't have fewer than for answers!" },
         ],
    },
    {
        'id': "Q2",
        'text': "Is this another question?",
        'answers': [
            { 'id': 'Q2A', 'text': "Unimaginative answer" },
            { 'id': 'Q2B', 'text': "Dull answer" },
            { 'id': 'Q2C', 'text': "Boring is a town in Oregon" },
            { 'id': 'Q2D', 'text': "Can't handle any more answers" },
        ],
    },
]};

into the following HTML in the browser:

<section class="slide question">

<h2>Is this is a question?</h2>

<ol>

<li>An answer</li>

<li>…</li>

<li>…</li>

<li>…</li>

</ol>

</section>

etc … etc

Up to this point, I had been content with generating whole HTML documents using either HTML::Template or Template-Toolkit, but, in this case, I wanted my application to serve a shell document which would then be populated using a JSON document to be retrieved a little later.

I looked at a number of JavaScript templating solutions such as _.template, mustache, pure and a few others I do not remember. String concatenation hell immediately pushed me away from _.template. With pure.js, I wasn’t able to understand the documentation enough to do anything other than the provided canned examples. And, I still don’t understand how to deal with nested data structures using mustache.js. All of my difficulties are no doubt due to my shortcomings, but that does not matter any more.

I was immediately able to understand how to solve my problem using Handlebars.js. Too bad that was the last one I tried.

First, I defined the template:

<script id="question-template" type="text/x-handlebars-template">

{{#each questions}}
<section class="slide question">

<h2>{{text}}</h2>

<ol>

{{#each answers}}
<li>{{text}}</li>
{{/each}}

</section>
{{/each}}

</script>

I don’t know about you, but, in my mind, this felt very similar to what I would have written with HTML::Template and I found that comforting.

Then, assuming Q holds the object mentioned above, it was a simple matter of getting the source of the template from the DOM, compiling it, rendering it with the appropriate context, and inserting it into the right place using JQuery:

var source   = $("#question-template").html();
var template = Handlebars.compile(source);
var html     = template(Q);

$('.deck-container').prepend(html);