Handling the Handlebars! – Tips and Tricks while using Handlebars.js

This post neither provides a detailed explanation of when to use templates and why to use them nor does it provide a tutorial on Handlebars.js. The reader is assumed to have a sufficient understanding of template systems and Handlebars in particular.

Handlebars is a template system which can be used to manage your templates.

But why do you need templates?

Complex projects require a lot of dynamic HTML manipulation. In older times when template systems were not developed,  software developers created new chunks of HTML code and dynamically inserted them into the DOM using Javascript. This eventually became unwieldy and difficult to maintain. Also, it lead to repetition of code. To solve this issue, template systems were created, using which predefined templates are used in different locations without repeating the code. Templates are like “macros”; wherever they are used, the code in them is inserted at that place. They also help to keep your html away from your javascript files, thereby increasing the readability and re-usability of your code.

Handlebars is one such template system.  While working on a project recently, I started using Handlebars to write templates. While it is quite an efficient library and performs a multitude of operations, most of its powerful features are “hidden” and not very clearly documented. This post aims at unearthing the hidden talent of Handlebars 😉  and to provide a few valuable tips and tricks while using it.

For understanding the features,  let’s use the below given context as an example.

var context = {
 'Fruits': {
	'Watermelon': ['Green'],
	'Apple' : ['Red', 'Green', 'Golden'],
	'Grapes' : ['Green', 'Black'],
 },
 'Vegetables': {
	'Tomato' : ['Red'],
	'Bell Pepper' : ['Green', 'Yellow', 'Red'],
	'Carrot' : ['Orange'],
 }
}

 1) Lookup operator :

The lookup helper allows accessing values inside a dictionary or an array using the key of the dictionary or an index of an array respectively.

For e.g.  To list all the fruits in your HTML,  use lookup as follows to fetch the fruits dictionary from the context :

 {{lookup context 'Fruits' }}

For fetching values inside an array, this is how it is done as given in the official documentation :

{{#each bar}}
  {{lookup ../foo @index}}
{{/each}}

The above example iterates over array “bar”, and for each index of array “bar”, fetches the corresponding value at that index position from array “foo”. Ignore the “../” for now, we will come to that later.

2) Sub-expressions :

Sub-expressions can be used to group together multiple helpers within a single mustache. The results of the inner helpers are passed to the outer helpers as arguments. Sub-expressions are represented using round brackets.

For e.g.  To list all the different colors of Bell Pepper,  use a sub-expression along with a lookup helper as follows :

 {{ lookup (lookup context 'Vegetables') 'Bell Pepper'}}

3) Access variables outside a context (../) :

Referring to the above example :

{{foo}}
{{#each bar}}
   {{lookup ../foo @index}}
{{/each}}

Here, inside the each loop, the context changes. Hence, to access a variable of the parent context  i.e “foo” ,  ‘../’ is used before the variable name inside the each loop. Keep adding a ‘../’  string to go up each additional level. For example, to go up two levels use ‘../../key’.

4) Access an array using index :

The lookup operator is one way to access an array using index. There is another way to do this.

Given the below context :

{
  people: [
    {"name": "Yehuda Katz"},
    {"name": "Alan Johnson"},
    {"name": "Charles Jolley"}
  ]
}

The first item in the array can be accessed in the following manner :

{{people.[1]}}

And the first name in the array can be accessed in the following manner :

{{people.1.name}}

 5) HTML Escaping :

If you don’t want Handlebars to escape a value, use the “{{{” operator,  i.e three curly brackets a.k.a mustaches.

{{{description}}}

with this context :

{description : "<i>test</i> 123"}

gives :

<i>test</i> 123

6) If Condition Helper :

Helpers are Javascript methods with custom logic which can be used inside the Handlebars mustaches. One such very commonly used and unfailingly required helper is the “ifCond” helper. The standard “if” helper in Handlebars provides only truthy / falsy values and cannot be used for comparisons. To solve this issue, a helper can be written. The below code is sourced from the following StackOverflow answer :

Handlebars.registerHelper('ifCond', function (v1, operator, v2, options) {

    switch (operator) {
        case '==':
            return (v1 == v2) ? options.fn(this) : options.inverse(this);
        case '===':
            return (v1 === v2) ? options.fn(this) : options.inverse(this);
        case '!=':
            return (v1 != v2) ? options.fn(this) : options.inverse(this);
        case '!==':
            return (v1 !== v2) ? options.fn(this) : options.inverse(this);
        case '<':
            return (v1 < v2) ? options.fn(this) : options.inverse(this);
        case '<=':
            return (v1 <= v2) ? options.fn(this) : options.inverse(this);
        case '>':
            return (v1 > v2) ? options.fn(this) : options.inverse(this);
        case '>=':
            return (v1 >= v2) ? options.fn(this) : options.inverse(this);
        case '&&':
            return (v1 && v2) ? options.fn(this) : options.inverse(this);
        case '||':
            return (v1 || v2) ? options.fn(this) : options.inverse(this);
        default:
            return options.inverse(this);
    }
});

This can be used like this :

{{#ifCond var1 '==' var2}}

 

These were just few tips and tricks which helped me while using Handlebars. The post will be updated as and when I find something worth adding to this list. If you have found something interesting while working on Handlebars, do share it in the comments section.

Happy coding!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: