Using Handlebars Templates With Backbone and Browserify

While working on a recent side-project, I ran into some trouble implementing Handlebars templates for my use in my backbone views when using Browserify for my dependency management. If you’ve run into similar issues, here’s a quick breakdown of what you’ll need to do to get up and running again:

1. Install Hbsfy

In order to precompile the templates for use in your app, you’ll need to install hbsfy and include it in your gulpfile. For the record, I have no idea what the hell that’s supposed to stand for but I like to imagine it being short for “Handlebars Sci-Fi” but spelled in the same way as the terrible TV network. Here’s a snippet from my gulpfile for you to use as a starting point.

    var gulp,
        browserify,
        del,
        gulp,
        hbsfy,
        sass,
        source,
        sourcemaps;

    gulp = require('gulp'); // Include gulp

    // Include our plugins
    browserify      = require('browserify');
    del             = require('del');
    hbsfy           = require("hbsfy"); // <---- THIS RIGHT HERE
    sass            = require('gulp-sass');
    source          = require('vinyl-source-stream');
    sourcemaps      = require('gulp-sourcemaps');
    //---
...

Apply Hbsfy During the Bundle Process

Once you’ve included Hbsfy, you’ll need to apply it as a transformation during the bundle() process:

...
    gulp.task('compile', function () {
        var options;

        options = {
            debug: true,
            paths: [
                './node_modules',
                './src/app/'
            ]
        };

        hbsfy.configure({
            extensions: ['hbs']
        });

        browserify('./src/main.js', options)
            .transform(hbsfy)
            .bundle()
            .pipe(source('app.min.js'))
            .pipe(gulp.dest('build/public/assets/js'));
    });
...

The one thing to note in the above snippet is the call to hbsfy.configure where I am simply telling hbsfy (I seriously want to know what that stands for) that my template files will all end in .hbs. You can substitute in whatever file format you’re using for your templates.

3. Include the Template in the Same File As Your Backbone View

Once you’ve got your gruntfile configured properly, you can safely start using Handlebars templates in your Backbone views…almost. You still need to include them. It’s rather straightforward:

(function () {
    'use strict';

    var User,
        Users,
        Handlebars,
        template,
        Backbone;

    Backbone = require('backbone');
    User = require('entities/user');
    Users = require('collections/users');
    Handlebars = require('handlebars');
    template = require('./search-full.hbs'); // <!-- RIGHT HERE
...

4. Override the Render Method of Your View and Call the Template

...
    module.exports = Backbone.View.extend({
        className: '.form',
        el: '#app',
        events: {
            'keypress .search .field': 'submitSearch'
        },
        initialize: function () {
            this.render();
        },
        render: function () { // <!-- OVERRIDDEN
            this.$el.html(template());
            return this;
        },
...

For the record, I’m not sure if this is the way to do this. However, I tried simply setting the value of the template property on the view and it didn’t work. If you know of a better way, feel free to leave a comment.

Wrapping Up

Well, I hope this eased someone’s frustrations out there. If it did or if you know of a better approach to this problem, please let me know in the comments below.

  • http://YourWebsite Nicholas Juntilla

    So after not getting data in my templates over and over again I finally figured out the hbsfy plugin is actually COMPILING the template. SO unlike everything else in browserify world hbsfy actually steps in and does the rendering so it solves 2 problems at once. UNFORTUNATELY the main problem of just pulling in the templates was the only one we really needed solving so I spent the last few hours trying to compile the string pulled in from HBSFY. Of course HBSFY has already parse out the {{}} which I only found out by console logging the entire string. So I’m grateful that it exists, but I really wish it would have just pulled in the file like everything else in browserify world as a simple hbs string and let me parse it. Anyway FYI anyone else once you require in the template you actually feed it the model or collection. Unfortunately it’s not just a template string.

    • http://YourWebsite Nicholas Juntilla

      I was thinking maybe this was so you could use it from the command line, but no I think it’s this way so you don’t have to pull in the handlebars library itself. So now we rely on hbsfy to bring in handlebars instead of compiling with our own handlebars. I still don’t really see the logic. Please people just solve one problem.

  • http://YourWebsite Devon

    great post — exactly what I was looking for. However, when I build this, the source maps aren’t coming through or aren’t being picked up by chrome/firefox. I notice that you included a require for sourcemaps, but never used it in your code — am I missing where to put that?