Getting a Handle on Handlebars

Here at EyeCue Lab we render most of our data-laden HTML pages in Handlebar templates. Handlebars.js is great for injecting snippets of JSON or other kinds of data objects straight into your HTML code. On the surface it seems constrained to a few useful applications, but with a few learned tricks it can become your new best friend.

The Basics

If you're brand new to Handlebars, take a quick look through the official documentation here before reading on.

Iteration & Indexes

Our first trick is for calling specific chunks of JSON. Normally in handlebars you just start at the top level and go down. So, for example, to get a last-name of a user you’d type {{}}. But what if there’s more than one attribute for an element? For example if you have multiple user names in your data object, you could definitely loop through them with their each function:

  {{#each users}}
      <h2>{{}} {{}}</h2>

However, if you want to call on a specific element in the nested object, you'll need to call it with an index. Unlike other languages, handlebars index syntax is a little... unorthodox. If the index number is in the middle of a chain it’s written like this {{actions.1.href}}. Except, if the index is at the end of a chain it’s written like this {{{[3]}}.

Luckily, that's not the only way to navigate through the object. You might have noticed that when we looped through our nested object above, the element itself is referred to as {{this}}. If you know the name of the object key, you can also use it directly, so instead of writing {{}} we could have just written {{}}. When outside a loop the object itself is referred to as simply {{.}} which useful for certain helper methods (I’ll explain in a bit). If you’re in a loop and you want to access previous elements of the object, you can use the syntax {{../this}} to go up a tier. If you want to keep moving up just keep chaining them together like so {{../../../this}}

Handlebar Helpers

Handlebars reduces much of it's limitations by letting you create a helper.js file that all of your HBS files will automatically read from. In here you can create JavaScript methods to use in with your handlebar templates called Helpers. For example, if you’re using '{{}}' and it’s coming out “matthew”. You can create a helper to capitalize the word for you. Check it out:

Handlebars.registerHelper('capitalize', function(str) {  
  return str.charAt(0).toUpperCase() + str.slice(1);

Probably looks familiar right? Just your run of the mill slice & dice JavaScript function for strings. And now that you’ve built a helper method, you can use it on the original handlebars object element like this {{capitalize}}. Just be careful not to name your helper functions with any word that might become a variable or object key name later on.

One more extremely useful handlebar helper that we've found let’s you do operator comparisons in the handlebars template. It’s a little long, but extremely useful. Check it out:

Handlebars.registerHelper('compare', function(lvalue, rvalue, options) {  
 if (arguments.length < 3)
 throw new Error("Handlerbars Helper 'compare' needs 2 parameters");

operator = options.hash.operator || "==";

 var operators = {
 '==': function(l,r) { return l == r; },
 '===': function(l,r) { return l === r; },
 '!=': function(l,r) { return l != r; },
 '<': function(l,r) { return l < r; },
 '>': function(l,r) { return l > r; },
 '<=': function(l,r) { return l <= r; },
 '>=': function(l,r) { return l >= r; },
 'typeof': function(l,r) { return typeof l == r; }

 if (!operators[operator])
  throw new Error("Handlerbars Helper 'compare' doesn't know the operator  "+operator);

 var result = operators[operator](lvalue,rvalue);

 if( result ) {
  return options.fn(this);
 } else {
  return options.inverse(this);

Now you can compare two Handlebar object values or a handlebar variable vs a string/boolean. Such as this:

{{#compare name “Johnson” operator=”==”}}
    <h1> {{name}} </h1>
    <h1> No name! </h1>

If you’ve gotten the gist of it, you can see that we’re comparing our handlebar variable {{name}} to the string “Johnson” using the equal operator. So in layman’s terms, does our name element equal ‘Johnson”? If the comparison returns true, then we render the name itself in the H1 tags. If not we display the string 'No name!'. You can mix and match this helper with {{#each}} loops and {{#if}} operators to create even more complex conditions.


I won't lie to you dear reader, navigating through and displaying nested objects in Handlebars can get confusing and hectic at times. For example, every time you iterate through part of the object it drops you down to the next tier automatically. So if we start with the object

data = {  
  users: {
    name: {[
       first: "Joe"
       last: "Johnson"

and loop through it twice:

{{#each users}}
    {{#each name}}

"This" is now either Joe Johnson's first or last name. If you tried to call {{users}} at this level, you wouldn't return anything since Handlebars is reading the data at this tier only. As mentioned before, you can go up tiers with {{../}, but knowing how many levels to jump up and down again can get confusing. This Helper method will get you out of said jam.

Handlebars.registerHelper("debug", function() {  
  console.log("HANDLEBARS DEBUG");

"Debug" will take whatever object level you're on and spit it out into the console. So if we had put {{debug}} in the middle of our loop, we would have spit out "Joe" and then "Johnson" on the next iteration. It's also helpful to place the Debug Helper at the top of your template to refer to as your building your page.