Handlebars provides the power necessary to let you build semantic templates effectively with no frustration.
Handlebars is largely compatible with Mustache templates. In most cases it is possible to swap out Mustache with Handlebars and continue using your current templates. Complete details can be found here.
<div class="entry"> <h1>{{title}}</h1> <div class="body"> {{body}} </div> </div>
{{
, some contents, followed by a }}
<script>
tag. <script id="entry-template" type="text/x-handlebars-template"> <div class="entry"> <h1>{{title}}</h1> <div class="body"> {{body}} </div> </div> </script>
<script>
tag. Do not put it into the HTML directly or the HTML-parser might modify it (for example, if it contains a table). Handlebars.compile
var source = document.getElementById("entry-template").innerHTML; var template = Handlebars.compile(source);
var context = {title: "My New Post", body: "This is my first post!"}; var html = template(context);
<div class="entry"> <h1>My New Post</h1> <div class="body"> This is my first post! </div> </div>Learn More: Execution
{{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>
{ title: "All about <p> Tags", body: "<p>This is a post about <p> tags</p>" }
<div class="entry"> <h1>All About <p> Tags</h1> <div class="body"> <p>This is a post about <p> tags</p> </div> </div>
Handlebars.SafeString
. If you write a helper that generates its own HTML, you will usually want to return a new Handlebars.SafeString(result)
. In such a circumstance, you will want to manually escape parameters. Handlebars.registerHelper('link', function(text, url) { text = Handlebars.Utils.escapeExpression(text); url = Handlebars.Utils.escapeExpression(url); var result = '<a href="' + url + '">' + text + '</a>'; return new Handlebars.SafeString(result); });
#
preceeding the helper name and require a matching closing mustache, /
, of the same name. {{#list people}}{{firstName}} {{lastName}}{{/list}}
{ people: [ {firstName: "Yehuda", lastName: "Katz"}, {firstName: "Carl", lastName: "Lerche"}, {firstName: "Alan", lastName: "Johnson"} ] }
list
to generate our HTML list. The helper receives the people
as its first parameter, and an options hash as its second parameter. The options hash contains a property named fn
, which you can invoke with a context just as you would invoke a normal Handlebars template. Handlebars.registerHelper('list', function(items, options) { var out = "<ul>"; for(var i=0, l=items.length; i<l; i++) { out = out + "<li>" + options.fn(items[i]) + "</li>"; } return out + "</ul>"; });
<ul> <li>Yehuda Katz</li> <li>Carl Lerche</li> <li>Alan Johnson</li> </ul>
else
section (used, for instance, by the built-in if
helper). options.fn(context)
, Handlebars does not escape the results of a block helper. If it did, inner content would be double-escaped! <p>{{name}}</p>
<div class="entry"> <h1>{{title}}</h1> <h2>By {{author.name}}</h2> <div class="body"> {{body}} </div> </div>
var context = { title: "My First Blog Post!", author: { id: 47, name: "Yehuda Katz" }, body: "My first post. Wheeeee!" };
../
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>
../
will resolve to varies based on the helper that is calling the block. Using ../
is only necessary when context changes, so children of helpers such as each
would require the use of ../
while children of helpers such as if
do not. {{permalink}} {{#each comments}} {{../permalink}} {{#if title}} {{../permalink}} {{/if}} {{/each}}
permalink
value even though they are located within different blocks. This behavior is new as of Handlebars 4, the release notes discuss the prior behavior as well as the migration plan. this
reference: <p>{{./name}} or {{this/name}} or {{this.name}}</p>
name
field on the current context to be used rather than a helper of the same name. {{!-- --}}
or {{! }}
. <div class="entry"> {{!-- only output author name if an author exists --}} {{#if author}} <h1>{{author.firstName}} {{author.lastName}}</h1> {{/if}} </div>
<div class="entry"> {{! This comment will not be in the output }} <!-- This comment will be in the output --> </div>
}}
or other handlebars tokens should use the {{!-- --}}
syntax. Handlebars.registerHelper
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}}</div> {{/each}} </div>
var context = { author: {firstName: "Alan", lastName: "Johnson"}, body: "I Love Handlebars", comments: [{ author: {firstName: "Yehuda", lastName: "Katz"}, body: "Me too!" }] }; Handlebars.registerHelper('fullName', function(person) { return person.firstName + " " + person.lastName; });
<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!</div> </div>
this
context of the function. <ul> {{#each items}} <li>{{agree_button}}</li> {{/each}} </ul>
var context = { items: [ {name: "Handlebars", emotion: "love"}, {name: "Mustache", emotion: "enjoy"}, {name: "Ember", emotion: "want to learn"} ] }; Handlebars.registerHelper('agree_button', function() { var emotion = Handlebars.escapeExpression(this.emotion), name = Handlebars.escapeExpression(this.name); return new Handlebars.SafeString( "<button>I agree. I " + emotion + " " + name + "</button>" ); });
<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 Ember</button></li> </ul>
Handlebars.SafeString
. true
, false
, null
and undefined
. {{agree_button "My Text" class="my-class" visible=true counter=4}}
<div class="post"> {{> userMessage tagName="h1" }} <h1>Comments</h1> {{#each comments}} {{> userMessage tagName="h2" }} {{/each}} </div>
Handlebars.registerPartial('userMessage', '<{{tagName}}>By {{author.firstName}} {{author.lastName}}</{{tagName}}>' + '<div class="body">{{body}}</div>');
var context = { author: {firstName: "Alan", lastName: "Johnson"}, body: "I Love Handlebars", comments: [{ author: {firstName: "Yehuda", lastName: "Katz"}, body: "Me too!" }] };
<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!</div> </div>Learn More: Partials
if
conditional and each
iterator.
© 2011–2017 by Yehuda Katz
Licensed under the MIT License.
https://handlebarsjs.com/