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