Getting Started with Handlebars.js
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:
HTML<script type="text/javascript" src="handlebars-v2.0.0.js"></script>
If you use a CDN link, it looks like this:
HTML<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:
BASHnpm install 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:
HTML<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.
JAVASCRIPT// grab the source
const source = document.querySelector("#introduction-template").innerHTML;
// compile it using Handlebars
const 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:
JAVASCRIPT// create context
const context = {
name: "Sabe"
};
// get the HTML after passing the template the context
const html = template(context);
Great, now the value of html
is set to:
HTML<p>Hello, my name is Sabe!</p>
Here is the final working version:
HTML<div class="introduction"></div>
<script id="introduction-template" type="text/x-handlebars-template">
<p>Hello, my name is {{name}}!</p>
</script>
JAVASCRIPT// grab the source
const source = document.querySelector("#introduction-template").innerHTML;
// compile it using Handlebars
const template = Handlebars.compile(source);
// create context
const context = {
name: "Sabe"
};
// get the HTML after passing the template the context
const html = template(context);
// get the element to set the new HTML into
const destination = document.querySelector(".introduction");
// set the new HTML
destination.innerHTML = html;
The result on the page is:
HTML<div class="introduction">
<p>Hello, my name is Sabe!</p>
</div>
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:
HTML<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:
JAVASCRIPTconst 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:
HTML<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, Handlebars 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.
HTML<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:
JAVASCRIPTconst context = {
name: "RIP Harambe",
artist: {
name: "Elon Musk",
recordLabel: "Emo G Records"
}
};
The resulting HTML is:
HTML<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.
JAVASCRIPTHandlebars.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:
HTML<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:
JAVASCRIPTHandlebars.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:
HTML<script id="uppercase-template" type="text/x-handlebars-template">
<h1>{{{#uppercase}}{{name}}{{/uppercase}}</h1>
</script>
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! Try handlebars for yourself and see what you can make with it!
Resources
- Handlebars.js Homepage
- Handlebars.js Installation Page
- Handlebars.js API Reference
- Try Handlebars.js Online
- Getting Started with TypeScript
- Create an RSS Reader in Node
- How to deploy a .NET app using Docker
- How to deploy a PHP app using Docker
- How to deploy a Node app using Docker
- Using Puppeteer and Jest for End-to-End Testing
- Build a Real-Time Chat App with Node, Express, and Socket.io
- Getting User Location using JavaScript's Geolocation API
- Learn how to build a Slack Bot using Node.js
- Getting Started with React
- Setting Up a Local Web Server using Node.js
- How To Create a Modal Popup Box with CSS and JavaScript