Block Helpers [Built-in & Custom]

In the last post, we discussed blocks and contexts. We used {{#each}} in that post, known as “Each Block Helper“. So, what is a block helper?

Block helpers make it possible to define custom iterators and other functionality that can invoke the passed block with a new context. [Handlebars Docs]

Handlebars give us some built-in block helpers which we can use. We can also create new helpers and register them to use. In this blog, we are going to study about some global helpers provided by default. Also, we will look at how to create a new helper and register them to use it.

Built-in Block Helpers

#1. Each

We discussed each block in the last post. Each helps us to traverse through an array/object which is passed as context/data to the helper. Let’s say we have data as follows :

var skills = {technologies:["PHP", "Javascript", "HTML", "CSS"]};



And we define our handlebars template as following :

<script type="text/x-handlebars-template" id="ex12">
    Some of the skills I know are : 
    <ul>
        {{#each technologies}}
            <li>{{this}}</li>
        {{#each technologies}}
 </ul>
</script>

Above will list all technologies in a unordered list.

#2. With

The with helper also works as each i.e to loop through an array but using with we can choose a specific context through which we wanna loop through. Handlebars by default take the current context but let’s say we want to target a different context from parent context then we can use “#with“. Let’s say the data and template are as follows we have :

data = {
    ul1: ['li1', 'li2'],
    ul2: [{li: 'li1'}, {li: 'li2'}],
    ul3: {firstName : 'kkk',lastName : 'mmm'}
};
{{#with ul3}} {{firstName}} {{lastName}} {{/with}},

The above example will output “kkk mmm“. The example will not work with each as it will be in current context and we will have to use {{this}} to traverse the object.

#3. If/Else

It works same as if blocks in Programming languages with only one difference it does not take conditional logic constructs. It only checks for truthy values [true, non-empty, non-null values].

{{#if userIsAdult}} Hello There {{else}} Hey Kiddo {{/if}}

In the above template if the key userIsAdult will have truthy value it will print “Hello There” else it will print “Hey Kiddo“.

#4. Unless

We can not use else helper used in above example on its own. It is a counterpart of if block. So for this, we have unless block helper. It is opposite of if block helper. If the statement is falsy, then it renders the contents inside it.

{{#unless userIsAdult}} Hey Kiddo {{/unless}}

We can also use “^” instead of unless and it will still work.

{{^userIsAdult}} Hey Kiddo {{/userisAdult}}

Custom Helpers

In addition to built-in helpers, Handlebars allows us to create our own custom helpers. Custom helpers can have complex logics and it will be written in JS and not in  Handlebars.  We will have to register our custom helpers before any Handlebars code.

There are 2 types of custom helpers in handlebars : 1. custom helper function and 2. custom helper block

1. Custom Helper function

This will be used without any blocks. Let’s say we want to greet the user depending on their country. As we can not have conditional statements in handlebars we will create a custom helper to achieve this.

Handlebars.registerHelper('greetUser', function(country) {
    var greet = '';

    switch(country.toLowerCase()) {
        case 'india' : 
            greet = 'Namaste';
           break;
        case 'usa' : 
            greet = 'Hello';
           break;
        case 'france' : 
           greet = 'Bonjour';
            break;
        case 'italy' : 
           greet = 'Ciao';
           break;
        default : 
            greet = 'Hi';
    }
 
    return greet;
});

Let’s say the data set is :

data = {
    people: [
        { country : 'india',first_name: "Prabhat" },
        { country : 'usa',first_name: "Nick" },
        { country : 'france',first_name: "Enzo" },
    ],
};

So the template will look like :

<script type="text/x-handlebars-template" id="ex10">
    {{#each people}}
       {{greetUser country}} {{first_name}}<br>
    {{/each}}
</script>

It will give us the following output

Namaste Alan
Hello Allison
Bonjour Nick

2. Custom Block Helpers

When we register a custom block helper, Handlebars adds a second parameter named options in the callback function.
This parameter is an object which has 2 methods : fn & inverse, and a hash object.

options.fn()

options.fn behaves like a normal compiled Handlebars template. The function will take a context and will return a String.

Handlebars.registerHelper('list', function(items, options) {
    var out = "<ul>";

    for(var i=0, l=items.length; i<l; i++) {
        out = out + "<li>" + options.fn(items[i]) + "</li>";
     }

    return out + "</ul>";
 });

In the above code, we are preparing a unordered list from the items array. We are using options.fn() method to concat the items to the HTML string.

options.inverse()

Handlebars provides the block for the else fragment as options.inverse. So when the expression results in truthy value we will use options.fn() and when it eavaluates to falsy we will use options.inverse().

Handlebars.registerHelper('checkEven', function(n, options) {
    if((n % 2) == 0) {
        return options.fn(this);
     } else {
        return options.inverse();
     }
 });
{{#modulo 10}} even {{else}} odd {{/modulo}}

In the above example, if the number is divisible by 2 we will print “even”[options.fn()]  else “odd” [options.inverse()]

options.hash

We can pass key-value pairs seperated by spaces also to Helper functions in Handlebars. To access this we can use options.hash object provided by Handlebars.

{{#hashTest age=12 name="Prabhat" country="India"}}
{{/hashTest}}
Handlebars.registerHelper ("hashTest", function (data, options) {
    console.log(JSON.stringify (options.hash)); 
});

We will get the following in the developer console.
{age:12, name:”Prabhat”, country:”India”}

There is a very nice git repo maintained by “assemble” where you can find very useful custom helpers defined. [https://github.com/assemble/handlebars-helpers]

Apart from this list you can define more custom helpers that can be specific to your business logic.

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