Writing a Handlebars Helper for Ember.js


Handlebars is a simple templating language that binds data to the HTML document. Handlebars templates keep our views nice and light by allowing us to inject data via Handlebars expressions––{{some-awesome-data}}.

In an Ember application, Handlebars will allow you to bind data to the DOM similarly to how ERB allows us to inject Ruby data from the server into a view in a Rails application. One downside of Handlebars expressions, however, if that we can't operate on or manipulate the Ember data objects that we render inside of them. This limitation, however, is actually a plus. It forces us to extract view-oriented logic into other, more appropriate places in our code.

One such location is the controller, which is responsible for decorating and/or modifying the Ember data that is sent by the router to the template. However, the controller is an appropriate place to alter the Ember data objects to be delivered to the template. What if we don't want to actually alter the data, but simply alter the way it is displayed? That's what Handlebars helpers are for!

What Are Handlebars Helpers?

Handlebars helpers are Javascript functions that are designed to help you control the way your data is rendered by the template in the browser for the client to view. There are a number of built-in helpers, such as {{#each}} and {{#if}}/{{else}} (which behave as you would expect them to).

We can use the {{#each}} helper to iterate over a collection of Ember data objects that have been routed to the template like so:

{{#each graduate in model}}
   {{#link-to 'graduate' graduate class="thumb"}}
    <img src="{{graduate.picture}}" class="grad-image"/>
   {{/link-to}}
 <div class="card-body">
    {{#link-to 'graduate' graduate}}
    <h2 class="name">{{graduate.firstName}} 
      {{graduate.lastName}}</h2>
    {/link-to}}
    <p class="post-meta">{{graduate.cohort}}</p>
    <p>{{short-bio graduate.bio}}</p>
 </div><!-- end card -->
{{/each}}

Our router is sending a collection of data, in this case Ember objects from the Graduate model, to the template. The {{#each}} helper is used to iterate over them and other helpers, such as {{#link-to}} provide us with additional functionality. For a bit more background on the app we're building helpers for, check out my earlier post.

You may have noticed that our render of each graduate's bio was prefaced with the short-bio. This is our custom Handlebars helper that was built to truncate the grad's bio in order to render a short, readable, excerpt followed by a classy .... Let's take a look:

Building a Custom Helper

Custom helpers belong in app/helpers. Custom helper can assist us in rendering Ember data in a particular way, like with our need to truncate a bio. They are especially helpful if you find yourself using the same HTML snippet again and again. In those cases, you can register a custom helper that can be invoked from any Handlebars template.

The file name of your custom helper should correspond to the helper name and any helper that has a multiple-word name, like "Short Bio", should separate the words with a -, e.g. short-bio.

In app/helpers/short-bio.js, we place the following code:

import Ember from 'ember';

export default Ember.Handlebars.makeBoundHelper(function(bio){
  if (bio.length > 200) {
	var theString = bio.substring(0,200) + " ... ";
	return new Ember.Handlebars.SafeString(theString);
  }

  else {
  	return bio;
  }

});

We register or establish our helper via the Ember.Handlebars.makeBoundHelper declaration. We tell our function to take in an argument (which will be the string of a grad's bio) and check if it is too long. If it is, we will grab a substring of the original string, chopping it off at the 200th character and appending "..." to the end. Lastly, we return a new Ember Handlebar's SafeString––this tells Handlebars not to escape the quotes around your string.

Now that we've built our helper function, we can call it in any template. Here's another look at the above usage:

{{#each graduate in model}}

    ...
    {{short-bio graduate.bio}}
    ...

This has been a brief look at building a custom Handlebars Helper for your Ember application. Now you're ready to go forth and built amazing Handlebars templates!

subscribe and never miss a post!

Blog Logo

Sophie DeBenedetto

comments powered by Disqus
comments powered by Disqus