Skip to content

Latest commit

 

History

History
145 lines (117 loc) · 4.49 KB

handlebars.md

File metadata and controls

145 lines (117 loc) · 4.49 KB

Setting up Handlebars

This recipe shows how to set up Handlebars to precompile your templates, including LiveReload integration.

Steps

1. Install dependencies

Install some gulp plugins:

$ npm install --save-dev gulp-handlebars gulp-define-module gulp-declare gulp-wrap gulp-concat

Install Handlebars as a bower component:

$ bower install --save handlebars
  • You need this so you can include the Handlebars runtime in your page – even compiled templates depend on this. (You won't need to include the entire Handlebars library though.)
// bower.json
{
  "name": "MyApp",
  "dependencies": {
    ...
  },
  "devDependencies": {
    ...
  },
  "overrides": {
    "handlebars": {
      "main": ["handlebars.runtime.js"]
    }
  }
}
  • It's a good idea to verify you've installed the same version of Handlebars as the one used by internally by gulp-handlebars, to guarantee compatibility between the runtime and your compiled templates. Look in node_modules/gulp-handlebars/package.json under "dependencies" and check the handlebars version – if necessary, you can ask bower to install that specific version, e.g. bower install --save handlebars#^1.3.0.

2. Create a templates task

gulp.task('templates', () => {
  return gulp.src('app/templates/*.hbs')
    .pipe($.plumber())
    .pipe($.handlebars())
    .pipe($.defineModule('plain'))
    .pipe($.declare({
      namespace: 'MyApp.templates' // change this to whatever you want
    }))
    .pipe($.concat('templates.js'))
    .pipe(gulp.dest('.tmp/templates'));
});

This compiles .hbs files into templates.js file in the .tmp/templates directory.

2.1 Using Partials

gulp.task('partials', function() {
  return gulp.src('app/templates/partials/*.hbs')
    .pipe($.plumber())
    .pipe($.handlebars())
    .pipe($.wrap('Handlebars.registerPartial(<%= processPartialName(file.relative) %>, Handlebars.template(<%= contents %>));', {}, {
      imports: {
        processPartialName: function(fileName) {
          // Escape the output with JSON.stringify
          return JSON.stringify(path.basename(fileName, '.js'));
        }
      }
    }))
    .pipe($.concat('partials.js'))
    .pipe(gulp.dest('.tmp/templates'));
});

This compiles the .hbs files inside the templates/partials directory into partials.js file in the .tmp/templates directory.

3. Add templates and partials as a dependencies of both html and serve

gulp.task('html', ['styles', 'templates', 'partials', 'scripts'], () => {
  ...
gulp.task('serve', ['styles', 'templates', 'partials', 'scripts', 'fonts'], () => {
    ...

4. Edit your serve task

Edit your serve task so that (a) editing an .hbs file triggers the templates task, and (b) the browser is reloaded whenever a .js file is generated in .tmp/templates:

 gulp.task('serve', () => {
-  runSequence(['clean', 'wiredep'], ['styles', 'scripts', 'fonts'], () => {
+  runSequence(['clean', 'wiredep'], ['styles', 'scripts', 'templates', 'partials', 'fonts'], () => {
     ...
     gulp.watch([
      'app/*.html',
      'app/images/**/*',
      '.tmp/fonts/**/*',
+     '.tmp/templates/**/*.js',
     ]).on('change', reload);

     gulp.watch('app/styles/**/*.scss', ['styles']);
+    gulp.watch('app/templates/*.hbs', ['templates']);
+    gulp.watch('app/templates/partials/*.hbs', ['partials']);
     gulp.watch('app/scripts/**/*.js', ['scripts']);
     gulp.watch('app/fonts/**/*', ['fonts']);
     gulp.watch('bower.json', ['wiredep', 'fonts']);
   });
 });

Usage

Put your .hbs files in app/templates and app/templates/partials (if you using partials), and include in your HTML after the bower components:

   <!-- build:js scripts/vendor.js -->
   <!-- bower:js -->
   ...
   <!-- endbower -->
   <!-- endbuild -->

   <!-- build:js scripts/main.js -->
+  <script src="templates/templates.js"></script>
+  <script src="templates/partials.js"></script>
   <script src="scripts/main.js"></script>
   <!-- endbuild -->

You would then render the template like this:

const html = MyApp.templates.foo();

The MyApp.templates namespace can be anything you want – change it in the templates task.