0% found this document useful (0 votes)
37 views8 pages

Handlebars.js Template Guide

Handlebars.js is a templating language that allows embedding expressions in HTML. It provides features like templates, blocks, helpers, and escaping to build semantic templates effectively. Templates can access nested properties in data and helpers can generate custom HTML. Handlebars compiles templates into functions that accept a context object and return HTML.

Uploaded by

Wharsojo Dev
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
37 views8 pages

Handlebars.js Template Guide

Handlebars.js is a templating language that allows embedding expressions in HTML. It provides features like templates, blocks, helpers, and escaping to build semantic templates effectively. Templates can access nested properties in data and helpers can generate custom HTML. Handlebars compiles templates into functions that accept a context object and return HTML.

Uploaded by

Wharsojo Dev
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Handlebars.

js: Minimal Templating on Steroids

Handlebars provides the power necessary to let you build semantic templates effectively with no frustration. Mustache templates are compatible with Handlebars, so you can take a Mustache template, import it into Handlebars, and start taking advantage of the extra Handlebars features.

Getting Started
Handlebars templates look like regular HTML, with embedded handlebars expressions.
<div class="entry"> <h1>{{title}}</h1> <div class="body"> {{body}} </div> </div>

A handlebars expression is a {{ , some contents, followed by a }}

You can deliver a template to the browser by including it in a <script> tag.


<script id="entry-template" type="text/x-handlebars-template"> template content </script>

Compile a template in JavaScript by using [Link]


var source = $("#entry-template").html(); var template = [Link](source);

In a future release, it will be possible to precompile Handlebars templates into JavaScript les to save time on the client.

Get the HTML result of evaluating a Handlebars template by executing the template with a context.
var context = {title: "My New Post", body: "This is my first post!"} var html = template(context);

results in
<div class="entry"> <h1>My New Post</h1> <div class="body"> This is my first post! </div> </div>

1 of 8

[Link]: Minimal Templating on Steroids

Handlebars HTML-escapes values returned by a {{expression}} . If you don't want Handlebars to escape a value, use the "triple-stash".
<div class="entry"> <h1>{{title}}</h1> <div class="body"> {{{body}}} </div> </div>

with this context:


{ title: "All about <p> Tags", body: "<p>This is a post about &lt;p&gt; tags</p>" }

results in:
<div class="entry"> <h1>All About &lt;p&gt; Tags</h1> <div class="body"> <p>This is a post about &lt;p&gt; tags</p> </div> </div>

Handlebars will not escape a [Link] . If you write a helper that generates its own HTML, you will usually want to return a new [Link](result) . In such a circumstance, you will want to manually escape parameters.
[Link]('link', function(text, url) { text = [Link](text); url = [Link](url); var result = '<a href="' + url + '">' + text + '</a>'; return new [Link](result); });

This will escape the passed in parameters, but mark the response as safe, so Handlebars will not try to escape it even if the "triple-stash" is not used.

Block Expressions
Block expressions allow you to dene helpers that will invoke a section of your template with a different context than the current. Let's consider a helper that will generate an HTML list:
{{#list people}}{{firstName}} {{lastName}}{{/list}}

2 of 8

[Link]: Minimal Templating on Steroids

If we have the following context:


{ people: [ {firstName: "Yehuda", lastName: "Katz"}, {firstName: "Carl", lastName: "Lerche"}, {firstName: "Alan", lastName: "Johnson"} ] }

we would create a helper named list to generate our HTML list. The helper receives the people as its rst parameter, and Function as its second parameter. Invoke the function with a context just as you would invoke a normal Handlebars template.
[Link]('list', function(items, fn) { var out = "<ul>"; for(var i=0, l=[Link]; i<l; i++) { out = out + "<li>" + fn(items[i]) + "</li>"; } return out + "</ul>"; });

When executed, the template will render:


<ul> <li>Yehuda Katz</li> <li>Carl Lerche</li> <li>Alan Johnson</li> </ul>

Block helpers have more features, such as the ability to create an else section (used, for instance, by the built-in if helper).

Built-In Block Helpers


The with Block Helper
Normally, Handlebars templates are evaluated against the context passed into the compiled method.
var source = "<p>{{lastName}}, {{firstName}}</p>"; var template = [Link](source); template({firstName: "Alan", lastName: "Johnson"});

results in
<p>Johnson, Alan</p>

3 of 8

[Link]: Minimal Templating on Steroids

You can shift the context for a section of a template by using the built-in with block helper.
<div class="entry"> <h1>{{title}}</h1> {{#with author}} <h2>By {{firstName}} {{lastName}}</h2> {{/with}} </div>

when used with this context:


{ title: "My first post!", author: { firstName: "Charles", lastName: "Jolley" } }

will result in:


<div class="entry"> <h1>My first post!</h1> <h2>By Charles Jolley</h2> </div>

The each block helper


You can iterate over a list using the built-in each helper. Inside the block, you can use
this to reference the element being iterated over.
<ul class="people_list"> {{#each people}} <li>{{this}}</li> {{/each}} </ul>

when used with this context:


{ people: [ "Yehuda Katz", "Alan Johnson", "Charles Jolley" ] }

will result in:

4 of 8

[Link]: Minimal Templating on Steroids

<ul class="people_list"> <li>Yehuda Katz</li> <li>Alan Johnson</li> <li>Charles Jolley</li> </ul>

You can use the this expression in any context to reference the current context.

The if block helper


You can use the if helper to conditionally render a block. If its argument returns false ,
undefined , null or [] (a "falsy" value), Handlebars will not render the block.
<div class="entry"> {{#if author}} <h1>{{firstName}} {{lastName}}</h1> {{/if}} </div>

when used with an empty ( {} ) context, will result in:


<div class="entry"> </div>

When using a block expression, you can specify a template section to run if the expression returns a falsy value. The section, marked by {{else}} is called an "else section".
<div class="entry"> {{#if author}} <h1>{{firstName}} {{lastName}}</h1> {{else}} <h1>Unknown Author</h1> {{/if}} </div>

The unless block helper


You can use the unless helper as the inverse of the if helper. Its block will be rendered if the expression returns a falsy value.
<div class="entry"> {{#unless license}} <h3 class="warning">WARNING: This entry does not have a license!</h3> {{/unless}} </div>

If looking up license under the current context returns a falsy value, Handlebars will render the warning. Otherwise, it will render nothing.

Handlebars Paths
5 of 8

[Link]: Minimal Templating on Steroids

Handlebars supports simple paths, just like Mustache.


<p>{{name}}</p>

Handlebars also supports nested paths, making it possible to look up properties nested below the current context.
<div class="entry"> <h1>{{title}}</h1> <h2>By {{[Link]}}</h2> <div class="body"> {{body}} </div> </div>

That template works with this context


var context = { title: "My First Blog Post!", author: { id: 47, name: "Yehuda Katz" }, body: "My first post. Wheeeee!" };

This makes it possible to use Handlebars templates with more raw JSON objects.

Nested handlebars paths can also include ../ segments, which evaluate their paths against a parent context.
<h1>Comments</h1> <div id="comments"> {{#each comments}} <h2><a href="/posts/{{../permalink}}#{{id}}">{{title}}</a></h2> <div>{{body}}</div> {{/each}} </div>

Even though the link is printed while in the context of a comment, it can still go back to the main context (the post) to retrieve its permalink. The ../ path segment references the parent template scope, not one level up in the context. This is because block helpers can invoke a block with any context, so the notion of "one level up" isn't particularly meaningful except as a reference to the parent template scope.

Helpers

6 of 8

[Link]: Minimal Templating on Steroids

Handlebars helpers can be accessed from any context in a template. You can register a helper with the [Link] method.
<div class="post"> <h1>By {{fullName author}}</h1> <div class="body">{{body}}</div> <h1>Comments</h1> {{#each comments}} <h2>By {{fullName author}}</h2> <div class="body">{{body}}</h2> {{/each}} </div>

when using this context and helpers:


var context = { author: {firstName: "Alan", lastName: "Johnson"}, body: "I Love Handlebars", comments: [{ author: {firstName: "Yehuda", lastName: "Katz"}, body: "Me too!" }] }; [Link]('fullName', function(person) { return [Link] + " " + [Link]; });

results in:
<div class="post"> <h1>By Alan Johnson</h1> <div class="body">I Love Handlebars</div> <h1>Comments</h1> <h2>By Yehuda Katz</h2> <div class="body">Me Too!</h2> </div>

Helpers receive the current context as the this context of the function.
<ul> {{#each items}} <li>{{agree_button}}</li> {{/each}} </ul>

7 of 8

[Link]: Minimal Templating on Steroids

when using this context and helpers:


var context = { items: [ {name: "Handlebars", emotion: "love"}, {name: "Mustache", emotion: "enjoy"}, {name: "SproutCore", emotion: "want to learn"} ] }; [Link]('agree_button', function() { return "<button>I agree. I " + [Link] + " " + [Link] + "</button>"; });

results in:
<ul> <li><button>I agree. I love Handlebars</button></li> <li><button>I agree. I enjoy Mustache</button></li> <li><button>I agree. I want to learn SproutCore</button></li> </ul>

8 of 8

You might also like