Handlebars - Partial

handlebars

What is a partial?

Handlebars partials are templates that can be shared among different templates. They are written as {{> partialName}}. Before using them in the HTML, we need to register the partial using Handlebars.registerPartial() method. The following example will help you in understanding how to register a partial named partialTemplate:

Handlebars.registerPartial(
  'partialTemplate',
  '{{language}} is {{adjective}}. You are reading this article on {{website}}.'
);

Context:
var context={
  "language" : "Handlebars",
  "adjective": "awesome"
}

Using a partial inside a template:
{{> partialTemplate website="sitepoint"}} <br>
{{> partialTemplate website="www.sitepoint.com"}}

Output:
Handlebars is awesome. You are reading this article on sitepoint
Handlebars is awesome. You are reading this article on www.sitepoint.com

In the above code, 'partialTemplate' is the name that we register for the partial / template. A partial is a template that can be shared among different templates.

Partials come in handy when you have a chunk of a Handlebars.js template that you need to use in a few different contexts. We use the Handlebars.registerPartial method to register a partial. It takes the name of the partial as its first argument and either a template source string or a compiled template as its second argument. The fact that it accepts a compiled template as the second argument is actually pretty useful. That allows you, for example, to use the partial in a loop that outputs a list but also append items to the list later using the partial’s template function.

To use a partial from a template, simply include > partialName. Here’s an example of using a partial:

<script id="people-template" type="text/x-handlebars-template">
  {{#each people}}
    {{> person}}
  {{/each}}
</script>

<script id="person-partial" type="text/x-handlebars-template">
  <div class="person">
    <h2>{{first_name}} {{last_name}}</h2>
    <div class="phone">{{phone}}</div>
    <div class="email"><a href="mailto:{{email}}">{{email}}</a></div>
    <div class="since">User since {{member_since}}</div>
  </div>
</script>

<script type="text/javascript">
  $(document).ready(function() {
    var template = Handlebars.compile($("#people-template").html());
    Handlebars.registerPartial("person", $("#person-partial").html());

    template(yourData);
  }
</script>

Handlebars partials allow for code reuse by creating shared templates.

Partial:
Handlebars.registerPartial('userMessage',
    '<{{tagName}}>By {{author.firstName}} {{author.lastName}}</{{tagName}}>'
    + '<div class="body">{{body}}</div>');

Template:
<div class="post">
  {{> userMessage tagName="h1" }}

  <h1>Comments</h1>

  {{#each comments}}
    {{> userMessage tagName="h2" }}
  {{/each}}
</div>

Context:
var context = {
  author: {firstName: "Alan", lastName: "Johnson"},
  body: "I Love Handlebars",
  comments: [{
    author: {firstName: "Yehuda", lastName: "Katz"},
    body: "Me too!"
  }]
};

Output:
<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>

Handlebars allows for template reuse through partials. Partials are normal Handlebars templates that may be called directly by other templates. In order to use a partial, it must be registered via Handlebars.registerPartial.

Handlebars.registerPartial('myPartial', '{{name}}');

This call will register the myPartial partial. Partials may be precompiled and the precompiled template passed into the second parameter. Calling the partial is done through the partial call syntax:

{{> myPartial }}

Will render the partial named myPartial. When the partial executes, it will be run under the current execution context.

What is a dynamic partial?

It's possible to dynamically select the partial to be executed by using sub expression syntax.

{{> (whichPartial) }}

Will evaluate whichPartial and then render the partial whose name is returned by this function. Sub-expressions do not resolve variables so whichPartial must be a function. If a simple variable has the partial name, it's possible to resolve it via the lookup helper.

{{> (lookup . 'myVariable') }}

Is it possible to execute partials on a custom context?

Yes. It's possible to execute partials on a custom context by passing in the context to the partial call.

{{> myPartial myOtherContext }}

What is a partial parameter?

Custom data can be passed to partials through hash parameters.

{{> myPartial parameter=value }}

Will set parameter to value when the partial runs. This is particularly useful for exposing data from parent contexts to the partial:

{{> myPartial name=../name }}

What is a partial block?

The normal behavior when attempting to render a partial that is not found is for the implementation to throw an error. If failover is desired instead, partials may be called using the block syntax.

{{#> myPartial }}
  Failover content
{{/myPartial}}

Which will render Failover content if the myPartial partial is not registered.

This block syntax may also be used to pass templates to the partial, which can be executed by the specially named partial, @partial-block. A template of

Main template using the partial named 'layout':
{{#> layout }}
  My Content
{{/layout}}

The partial named 'layout':
Site Content
{{> @partial-block }}

Output:
Site Content
My Content

As you can see, in the above code, the main template is executed first, and when it encounter the partial named layout, it executes the partial which produce 'Site Content' first, but the partial also contains {{> @partial-block }} which is 'My Content' (or the content of the block).

When called in this manner, the block will execute under the context of the partial at the time of the call. Paths and block parameters operate relative to the partial block rather than the partial template.

{{#each children as |child|}}
  {{#> childEntry}}
    {{child.value}}
  {{/childEntry}}
{{/each}}

Will render child.value from this template, not the partial.

What is an inline partial?

Templates may define block scoped partials via the inline decorator.

{{#*inline "myPartial"}}
  My Content
{{/inline}}
{{#each children}}
  {{> myPartial}}
{{/each}}

Which will render the myPartial partial for each child. Each inline partial is available to the current block and all children, including execution of other partials. This allows for layout templates and similar functionality:

Partial named 'layout':
<div class="nav">
  {{> nav}}
</div>
<div class="content">
  {{> content}}
</div>

Main template using the partial named 'layout':
{{#> layout}}
  {{#*inline "nav"}}
    My Nav
  {{/inline}}
  {{#*inline "content"}}
    My Content
  {{/inline}}
{{/layout}}

The inline partials (named nav and content) are visible and accessible to the current block and all children, including execution of other partials (namely the 'layout' partial).

Unanswered questions:

  1. Why should we bother with inline partials? By its definition, a partial is a re-usable template, and we probably should register it. Are we using inline partial so that we do not have to explicitly register it because it involve extra typing? Why do we need to register a partial anyway? Should we allow template to reuse other template without registration?
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License