Block helpers make it possible to define custom iterators and other functionality that can invoke the passed block with a new context.
<div class="entry">
<h1>{{title}}</h1>
<div class="body">
{{#noop}}{{body}}{{/noop}}
</div>
</div>
noop helper (short for "no operation") will receive an options hash. This options hash contains a function (options.fn) that behaves like a normal compiled Handlebars template. Specifically, the function will take a context and return a String. Handlebars.registerHelper('noop', function(options) {
return options.fn(this);
});
this, so you can invoke the block with this to evaluate the block in the current context. noop on the context object would be referenced using: {{./noop}}
<div class="entry">
<h1>{{title}}</h1>
<div class="body">
{{#bold}}{{body}}{{/bold}}
</div>
</div>
bold helper will add markup to make its text bold. As before, the function will take a context as input and return a String. Handlebars.registerHelper('bold', function(options) {
return new Handlebars.SafeString(
'<div class="mybold">'
+ options.fn(this)
+ '</div>');
});
with helper with helper demonstrates how to pass a parameter to your helper. When a helper is called with a parameter, it is invoked with whatever context the template passed in. <div class="entry">
<h1>{{title}}</h1>
{{#with story}}
<div class="intro">{{{intro}}}</div>
<div class="body">{{{body}}}</div>
{{/with}}
</div>
{
title: "First Post",
story: {
intro: "Before the jump",
body: "After the jump"
}
}
noop helper. Helpers can take parameters, and parameters are evaluated just like expressions used directly inside {{mustache}} blocks. Handlebars.registerHelper('with', function(context, options) {
return options.fn(context);
});
each helper works. <div class="entry">
<h1>{{title}}</h1>
{{#with story}}
<div class="intro">{{{intro}}}</div>
<div class="body">{{{body}}}</div>
{{/with}}
</div>
<div class="comments">
{{#each comments}}
<div class="comment">
<h2>{{subject}}</h2>
{{{body}}}
</div>
{{/each}}
</div>
each once for each element in the comments Array. Handlebars.registerHelper('each', function(context, options) {
var ret = "";
for(var i=0, j=context.length; i<j; i++) {
ret = ret + options.fn(context[i]);
}
return ret;
});
<ul> wrapper, and wraps each resulting element in an <li>. {{#list nav}}
<a href="{{url}}">{{title}}</a>
{{/list}}
{
nav: [
{ url: "http://www.yehudakatz.com", title: "Katz Got Your Tongue" },
{ url: "http://www.sproutcore.com/block", title: "SproutCore Blog" },
]
}
each helper. Handlebars.registerHelper('list', function(context, options) {
var ret = "<ul>";
for(var i=0, j=context.length; i<j; i++) {
ret = ret + "<li>" + options.fn(context[i]) + "</li>";
}
return ret + "</ul>";
});
Handlebars.registerHelper('list', function(context, options) {
return "<ul>" + context.map(function(item) {
return "<li>" + options.fn(item) + "</li>";
}).join("\n") + "</ul>";
});
if and unless control structures are implemented as regular Handlebars helpers. {{#if isActive}}
<img src="star.gif" alt="Active">
{{/if}}
Handlebars.registerHelper('if', function(conditional, options) {
if(conditional) {
return options.fn(this);
}
});
else functionality to block helpers. {{#if isActive}}
<img src="star.gif" alt="Active">
{{else}}
<img src="cry.gif" alt="Inactive">
{{/if}}
else fragment as options.inverse. You do not need to check for the existence of the else fragment: Handlebars will detect it automatically and register a "noop" function. Handlebars.registerHelper('if', function(conditional, options) {
if(conditional) {
return options.fn(this);
} else {
return options.inverse(this);
}
});
{{#if isActive}}
<img src="star.gif" alt="Active">
{{else if isInactive}}
<img src="cry.gif" alt="Inactive">
{{/if}}
unless helper could be used in the else portion as with any other helper. When the helper values are different, the closing mustache should match the opening helper name. list helper and make it possible for us to add any number of optional attributes to the <ul> element we will create. {{#list nav id="nav-bar" class="top"}}
<a href="{{url}}">{{title}}</a>
{{/list}}
options.hash. This makes it easier to accept a variable number of parameters, while also accepting an optional Hash. If the template provides no hash arguments, Handlebars will automatically pass an empty object ({}), so you don't need to check for the existence of hash arguments. Handlebars.registerHelper('list', function(context, options) {
var attrs = Object.keys(options.hash).map(function(key) {
return key + '="' + options.hash[key] + '"';
}).join(" ");
return "<ul " + attrs + ">" + context.map(function(item) {
return "<li>" + options.fn(item) + "</li>";
}).join("\n") + "</ul>";
});
Block helpers can also inject private variables into their child templates. This can be useful to add extra information that is not in the original context data.
For example, when iterating over a list, you may provide the current index as a private variable.
{{#list array}}
{{@index}}. {{title}}
{{/list}}
Handlebars.registerHelper('list', function(context, options) {
var out = "<ul>", data;
if (options.data) {
data = Handlebars.createFrame(options.data);
}
for (var i=0; i<context.length; i++) {
if (data) {
data.index = i;
}
out += "<li>" + options.fn(context[i], { data: data }) + "</li>";
}
out += "</ul>";
return out;
});
data option are available in all descendent scopes. index field of the parent iterator, @../index may be used. data field is defined prior to attempting to interact with an existing data object. The private variable behavior is condtionally compiled and some templates might not create this field. {{#each users as |user userId|}}
Id: {{userId}} Name: {{user.name}}
{{/each}}
user will have the same value as the current context and userId will have the index value for the iteration. {{#each users as |user userId|}}
{{#each user.book as |book bookId|}}
User Id: {{userId}} Book Id: {{bookId}}
{{/each}}
{{/each}}
blockParams options field. Handlebars.registerHelper('block-params', function() {
var args = [],
options = arguments[arguments.length - 1];
for (var i = 0; i < arguments.length - 1; i++) {
args.push(arguments[i]);
}
return options.fn(this, {data: options.data, blockParams: args});
});
{{#block-params 1 2 3 as |foo bar baz|}}
{{foo}} {{bar}} {{baz}}
{{/block-params}}
1 2 3 on render. options.fn.blockParams field, which is an integer count. This value represents the number of block parameters that could be referenced by the child template. Parameters beyond this count will never be referenced and can safely be omitted by the helper if desired. This is optional and any additional parameters passed to the template will be silently ignored. {{{{raw-helper}}}}
{{bar}}
{{{{/raw-helper}}}}
raw-helper without interpreting the content. Handlebars.registerHelper('raw-helper', function(options) {
return options.fn();
});
{{bar}}
© 2011–2017 by Yehuda Katz
Licensed under the MIT License.
https://handlebarsjs.com/block_helpers.html