LanguagesJavaScriptIntroducing JavaScript Templating with Handlebars.js

Introducing JavaScript Templating with Handlebars.js

Developer.com content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

Few languages have had as wild a career as JavaScript. The John Travolta of programming languages, the trajectory of JavaScript’s rocket to stardom was met with an equally bruising fall to earth before again suddenly establishing itself as an A-lister. These days everybody wants a piece of the language, and it seems to be playing a starring role across the Web.

JavaScript’s elevated status can largely be attributed to the Web’s migration away from traditional websites in preference of Web applications which mimic the interfaces and behavior of their desktop-bound brethren. Such applications tend to rely heavily on client-side JavaScript to produce highly responsive interfaces using a blend of complex layouts and Ajax. This paradigm presents a host of new problems to the developer, one of which pertains to the proper formatting of data returned from the server to JavaScript by way of an Ajax request. While it’s possible to inject the data into HTML elements using a server-side language, this approach can be strikingly clumsy for even mildly complex projects.

Developers have remedied this problem by creating JavaScript-based solutions which can deftly inject data stored in a JavaScript object into a template. One particularly popular solution is Handlebars.js. In this article I’ll show you how to start using Handlebars.js in conjunction to create highly manageable interfaces.

Installing Handlebars.js

To install Handlebars.js, either download it from GitHub or better, clone it:

$ git clone git://github.com/wycats/handlebars.js.git

Once downloaded, move the contents of the lib directory into a convenient location within your project directory structure, and reference handlebars.js within your page template:

<script src="/js/handlebars/handlebars.js" target="_blank"></script>

Creating a Handlebars.js Template

The Handlebars.js template syntax resembles that used by many templating solutions, using brackets to delimit the dynamic data placeholders. For instance, consider a project which involved creating an online trainer for learning Morse code. To insert two variables named letter and code into a Handlebars.js template, you would identify them like this:

{{letter}} - {{code}}

Typically you’ll pass dynamic data around in JavaScript using an object, meaning the letter and associated code might be stored like this:

var data = { alphabet: {
  letter: "A",
  code: ".-"
}};

Alternatively, you might like to render an array of objects in order to for instance create a complete alphabetical chart of the letters and their Morse code equivalents:

var data = { alphabet: [
    {letter: "A", code: ".-"},
    {letter: "B", code: "-..."},
    {letter: "C", code: "-.-."},
    {letter: "D", code: "-.."},
    {letter: "E", code: "."}
  ]};

In either case you can use the same template in conjunction with a Handlebars.js Block to render the results. Let’s start with the template:

<script id="alphabet" type="text/x-handlebars-template" target="_blank">
  <table>
    <thead>
      <th>Letter</th>
      <th>Code</th>
    </thead>
    <tbody>
      {{#alphabet}}
        <tr>
          <td>{{letter}}</td>
          <td>{{code}}</td>
        </tr>
      {{/alphabet}}
    </tbody>
  </table>
</script>

By embedding the template within a script element assigned the type text/x-handlebars-template, the template will automatically be hidden from the page until called upon by Handlebars.js. Within this template you’ll see the letter and code variables, both of which are embedded within a block named alphabet (the block opener is identified by the hashmark prefix).

Finally you’ll define the Handlebars.js code used to render the template (in this example I’m using jQuery to facilitate various JavaScript-related tasks):

$(document).ready(function() {

  var data = { 
    alphabet: [
      {letter: "A", code: ".-" },
      {letter: "B", code: "-..." },
      {letter: "C", code: "-.-." },
      {letter: "D", code: "-.." },
      {letter: "E", code: "." }
    ]
  };

  var layout   = $("#alphabet").html();
  var template = Handlebars.compile(layout);
  $("#chart").html(template(data));
});

The Handlebars.js-specific code really boils down to the last three lines. It begins by retrieving the template (identified by the alphabet DOM ID), and then compiles that layout into a JavaScript function (in the case of the above example, that function is named template). Finally, that function accepts the data as an argument, and the template output is displayed within an identified page element (in this case, a DIV assigned the ID chart).

Render this code within your browser and you’ll see the data presented in a manner similar to that found in Figure 1 (I say similar because I used a bit of CSS to tweak the table):

Rendering a Handlebars.js Template
Figure 1. Rendering a Handlebars.js Template

Using a Handlebars.js Helper

Handlebars.js includes a number of native helpers which allow you to use conditionals and introduce further clarity into the code. For instance, you can use the each helper to make abundantly clear what is happening in the previous template:

{{#each alphabet}}
  
    <td> </td>{{letter}}
    <td> </td>{{code}}
  
{{/each}}

Additionally, it’s possible to create your own helpers. For instance, suppose you wanted to conditionally link every code found in the previous display to an audio playback widget based on availability of an audio file. Rather than muddle up the template a conditional you can maintain it within a custom helper. To begin, I’ve modified the object array to include information which determines whether audio is associated with the letter:

var data = { 
  alphabet: [
    {letter: "A", code: ".-", audio: 0},
    {letter: "B", code: "-...", audio: 1},
    {letter: "C", code: "-.-.", audio: 1},
    {letter: "D", code: "-..", audio: 0},
    {letter: "E", code: ".", audio: 0}
  ]
};

Next create the helper:

Handlebars.registerHelper('audio_link', function(available) {
  if (available.audio) {
    return "<a href="player.html?letter=" + available.letter + "" target="_blank">Listen</a>";
  } else {
    return "N/A";
  }
});

Finally, to take advantage of the helper you can reference it by name within the template:

...

  <td> </td>{{letter}}
  <td> </td>{{code}}
  <td> </td>{{{audio_link this}}}

...

Render the revised code to the screen and you’ll see output similar to that presented in Figure 2.

Using a Handlebars.js Helper
Figure 2. Using a Handlebars.js Helper

Where to From Here?

Handlebars.js is one of several popular open source JavaScript templating solutions. Consider checking out Mustache, which is actually the inspiration for (and template-compatible with) Handlebars.js. Additionally, if you’d rather keep as much as possible within the jQuery family, check out the official jQuery Templates plugin.

About the Author

Jason Gilmore — Contributing Editor, PHP — is the founder of EasyPHPWebsites.com, and author of the popular book, “Easy PHP Websites with the Zend Framework”. Jason is a cofounder and speaker chair of CodeMash, a nonprofit organization tasked with hosting an annual namesake developer’s conference, and was a member of the 2008 MySQL Conference speaker selection board.

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories