GitHub

Handlebars - introduction

Publii uses Handlebars for theme creation. We have prepared a few predefined files which must be included in a basic theme. There are also a few additional files which can be added to a theme to achieve different layouts for a specific page like tags pages, authors pages, posts, pages, etc...

This article is an introduction to the most common Handlebars syntax elements which are necessary to create a theme in Publii.

How are Handlebars files rendered?

Handlebars are compiling *.hbs files and use context to render variables inside the template file.
A context is an object which contains data related to a current view.

In an example, if the context is an object like:

{
    "message": "Hello World!"
}

And the *.hbs file has the following structure:

<div>{{message}}</div>

Then we will receive as an output the following code:

<div>Hello World!</div>

Code blocks and context

Context can be an object with nested values i.e.: 

{
"message": {
"text1": "Lorem",
"text2": "Ipsum"
}
}

In this case, we have to ways to access the data in the object:

1) Access the specific field directly:

<div>{{message.text1}}</div> 

2) Access the specific filed using code blocks:

{{#message}}
<div>{{text1}}</div>
{{/message}}

Code blocks are usually more useful as it creates a natural structure of the content in your *.hbs files. But sometimes you will need to access in the block a field which is one or more levels above the current level of nesting.

In this case, you have to use the ../ prefix. In the example, if we have the following context:

{
config: {
option1: "value1"
},
message: {
text1: "lorem"
}

If we will use the code blocks method to access the nested fields variables and we will need to access config.option1 field, we will have to use a following syntax:

{{#message}}
<div>{{text1}}</div>
<div>{{../config.option1}}</div>
{{/message}} 

Conditional code blocks

Handlebars have two types of blocks - inline blocks and conditional blocks.

Conditional blocks can have two outputs depending on the condition - if it is true or false.

The simplest example of the conditional code block is the if block:

{{#if field}}
Text displayed if field in context is true
{{else}}
Text displayed if field in context is false
{{/if}

If you want to achieve a reversed behavior, you can use an unless conditional block:

{{#unless field}}
Text displayed if field in context is false
{{else}}
Text displayed if field in context is true
{{/unless} 

Of course, you can use a lot of more conditionals blocks. The main thing to remember is a fact that you should open it with the {{#NAME CONDITION}} syntax and close it with {{/NAME}} fragment.

Loops

You can iterate arrays and objects with the **#each** helper.

So if you have an array of arrays for each person in the project, you can use the following syntax:

{{#each persons}}
{{name}} - {{email}}
{{/each}}

 It can be used in the following context:

{
persons: [
{
name: "John",
email: "john@doe.com"
},
{
name: "Adam",
email: "adam@adam-and-eve.com"
}
]
}

The #each helper will generate a list of all persons in a list.

Custom elements

For Handlebars you can define two custom elements:

  • custom helpers,
  • custom partials

Custom helpers can be used for simple operations and also for conditional blocks.

Partials can be used for common parts of the themes.

In example Publii built-in themes partials can be used for:

  • Page header,
  • Page footer,
  • Social sharing block

Global variables

Some elements are common to all views and are used along with the normal context of the view.

It is called global variables - it is prefixed with an @ char.

Subscribe

Get the latest Publii news, updates and more delivered directly to your email inbox

You can change your mind at any time by clicking the unsubscribe link in the footer of any email you receive from us, or by contacting us at contact@tidycustoms.net. By clicking below, you agree that we may process your information in accordance with our Privacy Policy.