Better Templating with Partials in Handlebars and BackboneJS

One common problem that we face during BackboneJS is view management. Things are simpler when you are developing single page application. But when it comes to multi-page application in BackboneJS, it is common that views become unmanageable. Consider a situation where you are developing a mobile application in BackboneJS with multiple screens. Now you want that the header and footer should remain same throughout the application. There may be several strategies to handle this situation. Note that we have used Handlebars as templating system and the text plugin for reading templates.

Approach 1

The simpler way is that you can create two templates for header and footer and use them in all of your views. For example on your view you can write something like:

var page1 = Backbone.View.extend({
template: Handlebars.compile(require("text!templates/page1.html")),
render: function () {
var header_tpl = Handlebars.compile(require("text!templates/header.html"));
var footer_tpl = Handlebars.compile(require("text!templates/footer.html"));

this.$el.html(_self.template());
$("body .main").html(_self.$el);

//Add header and footer to body
$("body .header").html(header_tpl);
$("body .footer").html(footer_tpl);
}
});

So what’s wrong with this approach? I would say nothing. But think that you may have a lot of pages in your application and in each view’s render() function you will have to include the header and footer code. Moreover the html of header and footer is not a part of the main view page. So their content will not be available inside view’s $el object. You will not be able to add event handlers to header and footer in the view’s events object.

Approach 2: Using Partials

In this approach which I would prefer, we will create partials in Handlebars. These partials will be used in the templates and we need not to change anything in our view. Here is how to create partials using Handlebars and Backbone. In your app.js you can declare partials like:

define(function (require) {
//Define the header and footer partials for the Handlebars
//User these partials as {{>header}} anywhere in the templates
var header = Handlebars.compile(require("text!templates/header.html"));
Handlebars.registerPartial('header', header);

var footer = Handlebars.compile(require("text!templates/footer.html"));
Handlebars.registerPartial('footer', footer);
});

In your template use these partials as:
File page1.html:

{{>header}}

<div class="content"></div>

{{>footer}}

File header.html:

<div class="header">Header</div>

File footer.html:

<div class="footer">Footer</div>

Now in your view, you can write:

var page1 = Backbone.View.extend({
template: Handlebars.compile(require("text!templates/page1.html")),
render: function () {
this.$el.html(_self.template());
$("body .main").html(_self.$el);

//header HTML is available inside $el of this view
//$header = this.$(".header");
}
});

Benefits of this approach: 

  1. No need to add extra code in views. 
  2. You just need to change the templates. 
  3. The content of partials is available in the $el of the parent view. 
  4. Easy code management as views need not be altered when there is change in templates. 
  5. You can add event handlers on the partials added this way.

If you have a better solution, we can discuss that in comments 🙂

Written by Arvind Bhardwaj

Arvind is a Magento and WordPress expert with more than 6 years of industry wide experience.

Website: http://www.webspeaks.in/

3 thoughts on “Better Templating with Partials in Handlebars and BackboneJS

  1. you're truly a excellent webmaster. The site loading pace is incredible.

    It kind of feels that you're doing any unique trick.
    Also, The contents are masterpiece. you have done a great task on this subject!

  2. Yeah, totally impressed with the loading time of the site as well. You're using Ruby and WordPress, interesting.

  3. Hey I am so happy I found your webpage, I really found you by accident, while I was looking
    on Yahoo for something else, Anyways I am here now and would just like to say thank you for a fantastic post and a all round thrilling blog (I also love the theme/design), I don't have time
    to read it all at the moment but I have saved it and also added in your RSS feeds, so when I have
    time I will be back to read more, Please do
    keep up the great work.

Comments are closed.