Getting Started with Handlebars.js

Getting Started with Handlebars.js
namecheap placeholder image Handlebars.js is a templating engine that makes it easy to separate your HTML from the code that powers it, enabling you to write cleaner code. Because of this, Handlebars is popular, especially when you don't want to use a standalone front-end framework. This tutorial will give you an overview of the best Handlebars has to offer so you can get started using it as quickly as possible.

Installing Handlebars

Because it is just a JavaScript library, you can import it using a local path, a CDN link, or using a package manager like npm. If you want to host the file yourself, go to the Handlebars site and download the latest version. Should you choose to self-host it, it should look something like this:

	
    <script type="text/javascript" src="handlebars-v2.0.0.js"></script>
	

If you use a CDN link, it looks like this:

	
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/X.X.X/handlebars.js"></script>
	

Finally, if you choose to go down the npm route, install it by running this command:

	
    npm install --save handlebars
	

Either way, once installed, we can now dive into writing some templates.

Handlebar Templates

Templates for Handlebars are very similar to writing normal HTML, except that you can sprinkle some expressions in them which will be processed by Handlebars. Templates are added to the page and surrounded by script tags with a special type to prevent the browser from trying to parse them as JavaScript.

Here's an example of a basic Handlebars template:

	
    <script id="introduction-template" type="text/x-handlebars-template">
        <p>Hello, my name is {{name}}!</p>
    </script>
	

First you are going to want to grab and compile this template.

	
    // grab the source
    var source = document.querySelector("#introduction-template").innerHTML;

    // compile it using Handlebars
    var template = Handlebars.compile(source);
	

Since we are using a variable name, we need to provide Handlebars with the value before it can return to us the finalized HTML. We do this by passing it the context to the template:

	
    // create context
    var context = {
        name: "Sabe"
    };

    // get the HTML after passing the template the context
    var html = template(context);
	

Great, now the value of html is set to:

	
    <p>Hello, my name is Sabe!</p>
	

Here is the final working version:

	
    <div class="introduction"></div>
    <script id="introduction-template" type="text/x-handlebars-template">
        <p>Hello, my name is {{name}}!</p>
    </script>
	
	
    // grab the source
    var source = document.querySelector("#introduction-template").innerHTML;

    // compile it using Handlebars
    var template = Handlebars.compile(source);

    // create context
    var context = {
        name: "Sabe"
    };

    // get the HTML after passing the template the context
    var html = template(context);

    // get the element to set the new HTML into
    var destination = document.querySelector(".introduction");

    // set the new HTML
    destination.innerHTML = html;
	

The result on the page is:

	
    <div class="introduction">
        <p>Hello, my name is Sabe!</p>
    </div>
	
udemy2 placeholder image

Block Expressions

An extremely useful feature of Handlebars is their block expressions. They allow you to have different sections in the same template behave differently. A great example of why you would want this is when you are trying to iterate over a list or array. You want each item to access a different part of your context, and block expressions make this possible.

Consider an example where you have a list of cities and their populations. Here's how the template could look like:

	
    <script id="city-template" type="text/x-handlebars-template">
        <ul class="cities">
            {{#each cities}}
                <li class="city">{{name}}: {{population}}</li>
            {{/each}}
        </ul>
    </script>
	

And this is the context we can pass:

	
    var context = {
        cities: [
            {
                name: "New York City",
                population: 8623000
            },
            {
                name: "Los Angeles",
                population: 3971000
            },
            {
                name: "Chicago",
                population: 2716000
            },
            {
                name: "Houston",
                population: 2313000
            },
            {
                name: "Philadelphia",
                population: 1567000
            }
        ]
    };
	

The resulting HTML is:

	
    <ul class="cities">
        <li class="city">New York City: 8623000</li>
        <li class="city">Los Angeles: 3971000</li>
        <li class="city">Chicago: 2716000</li>
        <li class="city">Houston: 2313000</li>
        <li class="city">Philadelphia: 1567000</li>
    </ul>
	

Because we used the each block expression, Hanledbars automatically took care of iterating over the context that we passed in and generated the desired HTML.

Paths

Keep in mind that you can also access nested values in your context by using Paths. After all, this is JavaScript. Here is some context data about a song.

	
    <script id="nested-template" type="text/x-handlebars-template">
        <h1>{{name}}</h1>
        <h2>{{artist.name}}</h2>
        <h3>{{artist.recordLabel}}</h3>
    </script>
	

Notice how we're accessing a nested property by using a nested path to that property? This is the context we pass can look like this:

	
    var context = {
        name: "RIP Harambe",
        artist: {
            name: "Elon Musk",
            recordLabel: "Emo G Records"
        }
    };
	

The resulting HTML is:

	
    <h1>RIP Harambe</h1>
    <h2>Elon Musk</h2>
    <h3>Emo G Records</h3>
	

Helpers

When you are looking for some custom functionality, Handlebars lets you create custom helpers to accomplish tasks you define. Let's say you wanted Handlebars to capitalize a variable for you. You can register a custom helper to do just that.

	
    Handlebars.registerHelper("capitalize", function(string) {
        string = string || '';
        return string.slice(0,1).toUpperCase() + string.slice(1);
    });
	

Inside the registerHelper function, you can do whatever you want with the input and then return a final output. When used in a template, it looks like this:

	
    <script id="capitalize-template" type="text/x-handlebars-template">
        <h1>{{capitalize name}}</h1>
    </script>
	

In this example, whatever the value of name is when you pass the context, it will be capitalized in the final output. Handlebars also lets you work with not just a single variable, but entire sections of a template. If you wanted to uppercase an entire sections of a template, you can use a block helper. A block helper is similar to a normal helper except it works on a block instead of just a variable.

Here's how to register a block helper:

	
    Handlebars.registerHelper("uppercase", function(string) {
        return options.fn(this).toUpperCase();
    });
	

What we're doing here is calling fn, which is the compiled template between the opening and closing blocks of our helper, and then passing in the context, in this case, this. Here's what the template could look like:

	
    <script id="uppercase-template" type="text/x-handlebars-template">
        <h1>{{{#uppercase}}{{name}}{{/uppercase}}</h1>
    </script>
	
siteground placeholder image

Conclusion

Hopefully this tutorial has helped you with the basics regarding Handlebars. It's a very powerful templating engine and if you plan to use it, definitely look at the full documentation on their website so you can be aware of all the different things it can do for you!

Resources

If you learned from this tutorial, follow us on Facebook, Twitter and LinkedIn! 😊 Also, join the conversation over at our official forum!