Handlebars in Express – basics
In my first node / express project, I decided to use Handlebars as the view engine. I took a look at various possible engines and I found this one the most acceptable to me. Not because its features and not as a result of deep analysis – I simply don’t like the syntax of Jade or Pug. Once I will play a little with this one, I will check others.
Variables
Once the skeleton of the application was generated, I took a look at the views directory. I found three files there: index.hbs, error.hbs and layout.hbs. The layout file is holding the main layout of the site, with the whole HTML structure. In header there is one variable used, in the title tag:
<title>{{title}}</title>
In the body of the file, I found one more:
{{{body}}}
You may ask: why the title variable is placed in double curly brackets and the body variable is placed in the triple brackets? Double brackets values are escaped, this means that HTML unsafe characters will be replaced with the entities. For example: if I will put ‘<p>About us</p>’ in the title variable, it will be replaced with ‘<p>About us</p>’. This is handy for all places where you want to pass simple values or text which is not formatted with HTML. Also – it is better from the security point of view – if given variable is filled with the data passed by the client, all XSS payloads should be neutralized.
Tripple curly brackets, on the other hand, are not escaping variable values. This is used to place HTML pieces of code, such as the content generated somewhere else.
Templates and layouts
When I opened my application in the browser for the first time, it already had the basic layout applied (layout.hbs) and it used the basic template file (index.hbs) to display contents of the page. The call to the handlebars view engine is rather easy, I found it in the routes/index.js file:
res.render('index', { title: 'Value of my title' });
This simply tells the application response object to render response using the index.hbs template. As you can see, variables are passed as the second argument of the call. I passed only my title value, but you can create more variables. Handlebars are skipping variables which are not in use on given template and layout. On the other hand, if you will not define title variable, it will be left blank.
During the rendering process, index.hbs template was used, filled with data and placed into {{{body}}} variable of the layout (taken from the layout.hbs file). This means that you don’t have to worry about including layout – it is simply handled for you by the handlebars engine.
What if I want to use another layout somewhere else?
I noticed that my user area (for logged in users) should use a different layout. I want to display different menu, most likely use different CSS file, alter general structure of the site. In handlebars using different layout means simply that you will have to tell the engine which layout to use. By default, the layout.hbs is used but if you will create additional one (let’s say userArea.hbs) you can tell the engine to use it by passing its name in the variables:
res.render('index', { title: 'Value of my title', layout: 'userArea' });
Simple, isn’t it? Please note that I used the file name without the extension. I can now create various layouts for various areas of my site.
Partials – reusable pieces of code
I’m using the same footer on various pages. I want to use it in various layouts. It will be not good to copy the same piece of code between my layouts. Each adjustment in such case will have to be copied too. This is one of the reasons to use partials – reusable pieces, reusable templates. To start using them you will have to add some code to your app.js file:
var hbs = require('hbs'); hbs.registerPartials(__dirname + '/views/partials');
You are now including hbs module and you are telling hbs engine to register all files located in /views/partials directory as partials. Let’s create our first partial, title.hbs:
<title>{{title}}</title>
I simply copied the part of the layout to my partial file. I will now adjust the layout to use it – in the place where the title was located, I will use:
{{> title}}
This will cause handlebars engine to generate the content using title partial. I know that this is a silly example, but a good point to start.
What will come next?
Now, once I have basic knowledge of handlebars, I will try to write menu generator to handle proper menu item highlighting based on currently opened page. This will require some additional features of handlebars to be used.
You can find this project source on GitHub.