I recently started working in the Open Event Webapp project. One of the initial issues that I took up was a trivial UI bug. It was about adding sponsor names beneath sponsor images for better representation. The issue can be found here. On reading up the code base and exploring the project a bit, I came across a new template – Handlebars.js. Handlebars is a template which has it’s base with the Mustache templating language. One of the early discoveries that I made with Handlebars.js was the use of {{ }} and {{{ }}} and the basic difference between them. In general, all Handlebar.js expressions, just like in Mustache templating, are written between {{ }} or {{{ }}} type of brackets. That is how I learned to identify and distinguish Handlebars from core HTML, even though they are inter-linked. The official Handlebars documentation describes Handlebars expressions in the following way:
“ A handlebars expression is a {{, some contents, followed by a }} ”
Getting started with Handlebars.js
Installation:
For a basic Linux installation, type the following in your command line:
npm install --save handlebars
Including Handlebars in HTML:
<script src="handlebars-v4.0.10.js"></script>
Handlebars templates are often stored in .hbs files for better readability and accessibility. The Open Event Webapp project consists of a handlebars .hbs file for each of the tracks, events, rooms, schedule, sessions and speakers templates. These can be found here, that is under src/backend/templates folder.
Difference between {{ }} and {{{ }}}:
Handlebars enables developers to print raw HTML tags or code with the help of {{{ }}}. On the contrary, if you don’t want to print HTML (which is usually the case), use {{ }}. For better understanding, let’s take an example.
If our JS has an object that looks something like:
$(function () { var templateScript = $("#title-template").html(); var temp = Handlebars.compile(templateScript); var Title= { “title”: <a> Handlebars</a> }
Then, HTML of the following kind will help to distinguish the {{ }} and {{{ }}} brackets.
<script id=”title-template” type=”text/x-handlebars-template”> {{title}} {{{title}}} </script> //the first line will contain an anchor tag with the name “Handlebars” //the second line will contain “<a>Handlebars</a>”
Block helpers in Handlebars:
Block helpers are identified by a ‘ #’ and they help to define and access custom iterators.
Handlebars allow calling JavaScript functions with the help of ‘helpers’. It doesn’t allow direct JavaScript code in the HTML with templates. We can create our own helpers using Handlebars.registerHelper () in our JavaScript. We generally pass a function to the helper. A good example was provided in the Handlebars.js documentation:
Handlebars.registerHelper('noop', function(options) { return options.fn(this); });
By default, Handlebars helpers take the current context as the context to pass(“this”). Other fields are overshadowed. Incase, we want to access one of the fields that is masked by the default “this” context, we have to use a path reference.
Iterations using helpers:
Helpers can be a great way to iterate over lists or objects. I will demonstrate it with an example from the Open Event Webapp project. To display all the sponsors of an event in the home page of the event Webapp, we use the following handlebars code, where we iterate over the object list “sponsorpics” that we have. It looks something like this:
{'1': ['Oreilly', 'Amazon'], '2': ['Huawei', 'Google'],'3': ['RedHat', 'GitHub']}
{{#if eventurls.sponsorsection}} <div class="sponsor-container"> <section class="sponsorscont"> <div class="row sponsor-row"> <div class="col-sm-12 col-md-12 col-xs-12 text-center"> <h1 class="section-header">Proudly supported by</h1><br> </div> </div> <div class="row"> <div class="col-sm-10 col-sm-offset-1"> <div class="row"> {{#each sponsorpics}} {{#each this}} <div class="{{{divclass}}}"> <div class=" {{{sponsorimg}}} text-center"> <a href="{{{url}}}" data-toggle="tooltip" title="{{{type}}}"> <img class="lazy centre {{{imgsize}}}" alt="{{{name}}}" data-original="{{{logo}}}"> </a> {{{name}}} </div> </div> {{/each}} {{/each}} </div> <!-- sponsor-row --> </div> </div> </section> </div> {{/if}}
For your reference, you can view a sample Webapp for the OSCON 2017 event here.
For further information, please refer to Handlebars.js .
An interesting tutorial about Handlebars in 10 mins or less can be found here.