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>