Handlebars.js & WordPress Template Parts: A Very Good Thing

Posted: February 27, 2012 Comments(2)

I’ve lost count of how many times throughout the early stages in my career I’ve made the mistake of including markup in my JavaScript. I knew it was wrong, but often didn’t find the time to research better methods due to time and/or budget restrictions. Thankfully, a number of really smart people have taken the issue by the neck & come up with a very elegant solution for a vast audience.

I remember first discovering jQuery.tmpl and things changing for me. Semantic, logic-less templates have since gone up like a flare, and we’re all better for it. The leaders in the arena are Handlebars and Mustache. Handlebars touts itself as an extension of Mustache and it’s just that. Handlebars is a progression of Mustache templates and offers some extra functionality I’ll likely use at some point, but haven’t needed to rely on to a great extent quite yet.

WordPress Templating with Handlebars

A templating system like Handlebars does everything we need to help us keep markup out of our scripts, which is otherwise a mashup recipe for maintenance disaster. Handlebars provides us the ability to modify the markup that makes a certain module within your view both easier to work with & update over time without having to edit the same markup in two places.

With a static implementation this is really great, but things get slightly more complicated when we’re working with a dynamic site like something powered by WordPress. The key is to remain DRY with both your WordPress template and your Handlebars template, but how?

I’ve found that the best way to do just that is through making use of WordPress’ get_template_part() and in doing so write both the markup and the Handlebars at once. Before we start examining some code, let’s define the problem we’re looking to solve using Handlebars and get_template_part(). Let’s say the client site we’re working on has a Team section and we’d like to call out a random Team member on the Home page and include a link that will replace the current member details with info about another (random) Team Member.

Under normal circumstances, we could accomplish this by setting up a Team Page in WordPress and then child Pages for each Team member, using the Featured Image for the headshot. To illustrate this example, have a look at the demo site that has been set up. A look at the WP admin shows we’ve just set up a simple Page structure.

Our goal here will be to set up a DRY implementation of our custom page template for our home page that makes use of both Handlebars.js and get_template_part() to pull a random Team member on page load, and upon clicking the Refresh link, details for another Team member will be displayed. get_template_part() is much like a WordPress version of include but more adaptable for things like Child themes. Additionally it allows two parameters which represent file name segments, which help with organization. Our first step will be to write our Home Page theme template.

There’s quite a bit going on here so let’s break it apart into a few sections. We start by defining a couple of globals, $post and $handlebars. $post is one of WordPress’ favorite globals, and $handlebars will be used to help us effectively embed our Handlebars template. Next we go ahead and enqueue jQuery and Handlebars for use on the page. We’ll use the WordPress-provided version of jQuery, and Handlebars will be an asset within our theme. From there we fire the usual suspects: the_post() and get_header().

Taking a look at <div id="primary"/> we see that we’re extending Twenty Eleven with a new instance of WP_Query which grabs a random Team member record for us. We’re outputting their details using get_template_part() and appending our Refresh link below that. We’ve also set up a JavaScript variable that’s going to help us keep track of the currently displayed Team member (as a way of preventing duplicates from showing up in sequence). The last call in this section is to wp_reset_postdata() which returns our $post to its original Loop.

The next thing we’ll take a look at is our Mustache.js template setup, this is where things get more applicable. We’re going to set our flag for $handlebars = true; just prior to calling get_template_part() one more time, referencing the same exact template file as we did in <div id="primary"/>.

If you’re not familiar with Handlebars, you’ll notice the intriguing method of defining Handlebars templates. Of particular note is the script type in this case. We’ve a script block type as not text/javascript, and in doing so it will not be executed as you might expect but instead stored for reference later much like an HTML node. This is a foundational principal of Handlebars existing at all.

We’re now left with the need to write the actual template part, team-member-spotlight.php:

Here we’ve gotten a bit creative in that we’re using this file for two purposes, both the native call to get_template_part() in addition to prepping our Handlebars template. You’ll notice that depending on $handlebars being true or false PHP will echo either our desired variables or the Handlebars equivalent, leaving us with Team member details in the markup and a Handlebars template that looks something like this:

We’re able to use the same template part to generate both our initial markup as well as the equivalent Handlebars template, providing a single file to work with as the site is maintained.

The last bit we set up is the click handler for our Refresh link. We’re going to bind to the click event of that link and when fired we’ll prevent the default action and proceed to make an ajax request to our Team page, and in doing so pass along some POST data that’s going to let us determine whether or not we’re working with an ajax request. Upon receipt of a successful ajax call, we’re going to parse the returned JSON into a JavaScript object, apply the Handlebars template, and swap out the markup.

The main Team page of the demo site acts as an overview for the Team as a whole, and each Team member has their own page as well, which is linked to directly from the home page. It’s also going to act as a handler for the ajax requests by making use of a new custom template file.

This template file begins by checking for our POST request, and if present will use the passed variables to grab data for a new Team member and avoid the current person being displayed. We create an array of the details we need, encode it as JSON and return it. If the POST data isn’t present, it means a standard page request has taken place, and we proceed in showing the rest of the template.

Please keep in mind that these demo files were set up for example’s sake and your assets should be much more organized than those put on display here.

Mustache helps you stay DRY

While barely scratching the surface of what Mustache can do, I like the fact that there are two byproducts of embracing logic-less templates via Mustache within your WordPress sites:

  1. Markup stays where it belongs and doesn’t needlessly get mixed with my JavaScript
  2. The markup only gets written once, making maintenance much easier and improving overall code quality

The most advanced thing I took advantage of in the example here is Mustache’s if block helper which allows you to conditionally render a block of markup based on a falsy value. Comparing that to what Mustache can do doesn’t hold a candle to it’s full feature set, but I hope helps to expose how you can use it in your WordPress projects. As you find yourself in more advanced circumstances where Handlebars would be of great use, there are many more features that can make your Handlebars templates that much more adaptive and powerful.

Are you using Handlebars in your projects? If so, what has been your favorite way to use logic-less templates?

Get my newsletter

Receive periodic updates right in the mail!
  • This field is for validation purposes and should be left unchanged.

Comments

  1. thanks for this detailed explanation, I was just looking into using handlebars with WordPress, but it’s still a bit confusing to me.
    I was trying to adapt some code from a nettuts tutorial into a widget plugin for Flickr photos, but for some reason if I add 2 widgets on the page, they both get the same images even though the parameters are different.
    https://github.com/pdewouters/FlickrBoss-plugin/blob/master/includes/flickrboss-widget.php

    so curious as to how you would adapt the team member highlight to a widget that could accept a department parameter, that way you could a widget per team in the sidebar

  2. This post got me very excited.

    I immediately thought of combining your approach with something like Custom Field Suite or ACF repeating fields in the primary page as special fields below the main content editing block for ease of management. Thus you would have a page that looked like:

    —team page content editor—

    —team person 1—————
    —team person 2—————
    —add team person 3———-

    By passing this data from repeating fields you can keep your pages much cleaner, organized.

    Furthermore, by doing something like this you could also auto-turn that info into a short code and include it anywhere in the primary content section.

    Taking that one step further you could then add some analytics to this approach and monitor A/B style which content has the highest conversion rate.

    Awesome work!

Leave a Reply

Your email address will not be published. Required fields are marked *