The Golden Middle Path - a blog by Amit K Mathur


Handlebars is a templating system – a language to write (mainly HTML) templates.

A template is a document with placeholder variables. A templating system can take a template, list of values for the variables used in the template and produce a final document. (Its like mail merge if you know what that is)

Input: template + variable values
Output: document produced by replacing the variables in the template with the values

Handlebars templating system has two main defining features:

  • It is logic-less. i.e. there are no if-then-else, no for-loops etc. That makes it easy for even non-programmers to write Handlebar templates.
  • It supports helpers. Using helpers, it is easy to extend Handlebars. There are two types of helpers: regular helpers and block helpers.

Although Handlebars compiler is available in several languages, it is mainly used with Javascript.

A simple example

If you have a template like this:

  <div class="product">
    This is a {{product}}.
    <span class="price">
     price: {{price}}.

And if your data looks something like this:

var data = {product: "shirt", price: 36.99};

Then the final document will be this:

  <div class="product">
    This is a shirt.
    <span class="price">
     price: 36.99.

Get your hands dirty

Install node.js

  $ git clone
  $ cd node
  $ make
  $ sudo make install
  $ export NODE_PATH=/usr/local/lib/node_modules # also add it to ~/.bashrc

Install npm – npm is package manager for node.

  $ curl -k | sudo sh -

Install Handlebars node package/module

  $ sudo npm install -g handlebars

Start a node session and try out Handlebars

  $ node
  > var Handlebars = require("handlebars"); // load Handlebars module
  > var template = "This is a {{product}}. Its price is {{price}}";
  > var compiled_template = Handlebars.compile(template);
  > var data = {product: "shirt", price: 36.99};
  > compiled_template(data) // this will print: 'This is a shirt. Its price is 36.99'


Handlebars makes it easy to access data even when the JSON hash is
hierarchical. For example, if your data were structured like:

var data = {"product": {"name": "shirt", "description" : "a nice summer shirt"}, price: 36.99}

you can write the template:

var template = "This is a {{}}. Its price is {{price}}";


Handlebars supports something called blocks (borrowed from Ruby blocks). Have
a look at this template:

    {{#each products}}

If you feed it the following data:

  products: [
    {name: "The Mythical Man Month", description: "Fred Brooks"},
    {name: "Godel Escher Bach", description: "Douglas Hofstadter"},
    {name: "More Programming Pearls", description: "Jon Bentley"}

It will produce the following output document:

      <h3>The Mythical Man Month<h3>
      <p>Fred Brooks</p>
      <h3>Godel Escher Bach<h3>
      <p>Douglas Hofstadter</p>
      <h3>More Programming Pearls<h3>
      <p>Jon Bentley</p>

There are several builtin block helpers: with, each, if and unless.

Defining your own helpers

Handlebars allows you to define your own helpers. Helpers are of two types: Regular Helpers and Block Helpers.

Regular Helpers

  Handlebars.registerHelper('availability', function(prod_data) {
    return prod_data.has_stock ? "In Stock" : "Out of Stock";

  var data = { product: {name: "The Mythical Man Month", has_stock: true, price: 34.99 } };
  var source = "{{}} is currently {{availability product}}";
  var template = Handlebars.compile(source);
  template(data); // Would render: 'The Mythical Man Month is currently In Stock'

When calling a helper, you can pass paths (like above) or strings (shown below) as parameters.

  var source = '{{upcase "in stock"}}' //Assuming you have defined a helper "upcase"

Block Helpers

Handlebars allows you to define your own block helpers to augment the built-in ones. Lets say you want to define a helper called prettify.

  Handlebars.registerHelper('prettify', function(options) {
    return '<div class="highlight">' + options.fn(this) + '</div>';

  var source = "<p>{{#prettify}}{{name}}{{/prettify}}</p>";
  var template = Handlebars.compile(source);
  var data = { "name": "Poor Little Rich Slum" };
  template(data); // renders: <p><div class="highlight">Poor Little Rich Slum</div></p>

Note that a helper, either regular or block helper, can take 0 or more arguments. In the above example availability helper takes 1 argument.

If a helper is used as a block helper, it will always get a hash as the last argument, called options in the above example. This options hash will contain a method called fn which behaves exactly like a compiled Handlebars template for the little template that’s enclosed between the block. (Ruby programmers will notice the similarity with ruby blocks)

Also, note that inside a helper, this always refers to the current context or the data.


You can register a template as a partial, which will be used by Handlebars when it encounters a partial ({{> partialName}}).

// Register a partial
var item = '<li><span id="{{id}}">{{name}}</span></li>';
Handlebars.registerPartial('menu_item', item);

// Optionally, you can compile the partial before registering.
// var compiled_item = Handlebars.compile(item);
// Handlebars.registerPartial('menu_item', compiled_item);

var source = "<ul>{{#each menu_list}}{{> menu_item}}{{/each}}</ul>";
var template = Handlebars.compile(source);
var data = { "menu_list": [{id : "home", name : "Home"}, {id : "about", name : "About Us"}, {id : "contact", name : "Contact Us"}] };
template(data); // this will render: <ul><li><span id="home">Home</span></li><li><span id="about">About Us</span></li><li><span id="contact">Contact Us</span></li></ul>


  • Handlebars HTML-escapes all variables by default. To not escape, use triple moustaches {{{ }}} or new Handlebars.SafeString("abc").
  • Handlebars is an extension of Mustache and all Mustache templates should work with Handlebars compiler.
  • Partials can either be string templates (as shown above) or they can be compiled template functions as well (as shown in the comment in the example above).
  • You can add comments to your templates with the following syntax:

  {{! This is a comment }}

  • Handlebars support pre-compiling. It is much faster to precompile the templates. Also, if you precompile, you only need handlebars.runtime.js to instantiate your templates into documents.



Post a comment

(Formatting help)