I’ve created a little helper that takes a partial name and a Ruby-like hash of parameters that will be passed into that partial:
Handlebars.registerHelper('include', function(partialName, options) {
var locals = options.hash,
context = this;
// the included partial also inherits the current context’s data
for (var property in context) {
if (property in data) return;
data[property] = context[property];
}
// it’s called with a block
if ('fn' in options) data['yield'] = options.fn(data);
var templateCode = document.querySelector('#' + partialName).innerHTML;
return new Handlebars.SafeString(
Handlebars.compile(templateCode)(data)
);
});
The key thing here is that Handlebars helpers accept a Ruby-like hash of arguments. In the helper code they come as part of the function’s last argument—options
— in its hash
member. This way you can receive the first argument—the partial name—and get the data after that.
It returns a Handlebars.SafeString
from the helper or use “triple‑stash”—{{{
— to prevent it from double escaping.
One other nice thing is that helper can also be passed a Ruby-like block, and the block will inherit the data context of the parent. The block content is injected in the included partial as the variable yield
, again, as in Ruby. One thing to note is that it’s output is not a SafeString
so you should use “tripple-stash” like this: {{{ yield }}}
.
Here is a more or less complete usage scenario:
<script id="text-field" type="text/x-handlebars-template">
<label for="{{id}}">{{label}}</label>
<input type="text" id="{{id}}"/>
</script>
<script id="checkbox-field" type="text/x-handlebars-template">
<label for="{{id}}">{{label}}</label>
<input type="checkbox" id="{{id}}"/>
</script>
<script id="form-template" type="text/x-handlebars-template">
<form>
<h1>{{title}}</h1>
{{{ yield }}}
</form>
</script>
<script id="form" type="text/x-handlebars-template">
{{#include 'form-template' }}
{{ include 'text-field' label="First name" id="author-first-name" }}
{{ include 'text-field' label="Last name" id="author-last-name" }}
{{ include 'text-field' label="Email" id="author-email" }}
{{ include 'checkbox-field' label="Private?" id="private-question" }}
{{/include }}
</script>