Coding with Jesse

Official jQuery Templating Plugin

October 11st, 2010

jQuery announced that they are now officially supporting jQuery Templates, thanks in big part to Microsoft.

Templating cleans up the job of generating HTML with jQuery. It also gives you the opportunity of keeping HTML code out of your JavaScript completely, if you wish.

Let's say you have a block of data like this:

var fruits = [
    { name: 'apples', color: 'green' },
    { name: 'oranges', color: 'orange' },
    { name: 'bananas', color: 'yellow' },
    { name: 'tomatoes', color: 'red' }
];

You want to display the data in a nice table with some color effects:

namecolor
apples green
oranges orange
bananas yellow
tomatoes red

Without templates, your code might look like this:

// create a table
var $table = $('<table class="fruit-table">');

// append a header to the table
$('<tr><th>name</th><th>color</th></tr>').appendTo( $table );

// append a row for each fruit
for (var i in fruits) {
    // create a row, and set the background to the color of the fruit
    var $row = $('<tr/>', { css: { background: fruits[i].color } });

    // create a column and append to the row
    // we use text here so all HTML is escaped, to prevent hacking
    $('<td/>', { text: fruits[i].name }).appendTo( $row );

    // do the same for the color
    $('<td/>', { text: fruits[i].color }).appendTo( $row );

    // append the row to the table
    $row.appendTo( $table );
}

// all done, stick the table on the page
$table.appendTo('body');

Unfortunately, code like this usually ends up looking kludgy, and it's often hard to visualize what the final HTML will look like.

Templates let us turn the HTML/JavaScript relationship inside-out by putting the looping right in the HTML:

// define a template for the fruit table
// we'll use slashes at the end of each line to escape the line break
// this way we don't have to concatenate strings.
$.template('fruit-table', '\
    <table class="fruit-table"> \
        <tr><th>name</th><th>color</th></tr> \
        {{each rows}} \
            <tr style="background: ${color}"> \
                <td>${name}</td> \
                <td>${color}</td> \
            </tr> \
        {{/each}} \
    </table> \
');

// instantiate the template with the fruit array passed in as 'rows'
var $table = $.tmpl('fruit-table', { rows: fruits });

// that's it. stick it on the page.
$table.appendTo('body');

Now there's no question what the HTML will look like. It's in plain view.

If you'd like to jump on the chance to take the HTML out of your JavaScript completely, you can stick the same block on the page, in a special <script> block:

<script id="fruit-table" type="text/x-jquery-tmpl">

    <table class="fruit-table">
        <tr><th>name</th><th>color</th></tr>
        {{each rows}}
            <tr style="background: ${color}">
                <td>${name}</td>
                <td>${color}</td>
            </tr>
        {{/each}}
    </table>

</script>

Now we're down to a single line of code. Beautiful, isn't it?

$('#fruit-table').tmpl({ rows: fruits }).appendTo('body');

Now that we've gotten that taken care of, let's take it to the next level, and make a template that will dump any tabular data we give it:

<script id="table" type="text/x-jquery-tmpl">

{{if !data || data.length == 0 }}
    <p>No data.</p>
{{else}}
    <table class="${className}">
        <tr>
            {{each(key) data[0]}}
               <th>${key}</th>
            {{/each}}
        </tr>
        {{each(i, row) data}}
            <tr>
                {{each(key, value) row}}
                    <td>${value}</td>
                {{/each}}
            </tr>
        {{/each}}
    </table>
{{/if}}

</script>

$('#table').tmpl({
    data: fruits,
    className: 'fruits-table'
}).appendTo('body');

Want more? Check out the documentation and official announcements for lots more information:

About the author

Jesse Skinner Hi, I'm Jesse Skinner. I'm a self-employed web developer with over two decades of experience. I love learning new things, finding ways to improve, and sharing what I've learned with others. I love to hear from my readers, so please get in touch!