Setup Handlebars with Sage
What is Sage?
Sage is a WordPress starter theme with a modern development workflow.
My Problem
I’ve used Handlebars templates in projects, but only simple way — I defined a <script> block in html templates and used in my js code. However, I have a project where need all the code including html templates as js files.
Installation
We need to do handlebars stuff at runtime, includes:
- Precompile templates by gulp during build time (install gulp-handlebars using npm)
npm install gulp-handlebars --save-dev
npm install gulp-wrap --save-dev
npm install gulp-declare --save-dev
- The web browser will execute the templates with handlebars-runtime library (install handlebars runtime using Bower).
bower install handlebars --save
Setup
- Create a new templates folder in assets folder where contains *.hbs files: /assets/templates/*hbs
- Add new templates gulp task, in gulpfile.js file:
// ...
var handlebars = require('gulp-handlebars');
var wrap = require('gulp-wrap');
var declare = require('gulp-declare');// ...// ### Templates
// gulp templates - Runs Handlebars precompilation on handlebar (*.hbs) files
gulp.task('templates', function() {
gulp.src('assets/templates/*.hbs').
pipe(handlebars()).
pipe(wrap('Handlebars.template(<%= contents %>)')).
pipe(declare({
namespace: 'MyApp.templates',
noRedeclare: true // Avoid duplicate declarations
}))
.pipe(concat('templates.js'))
.pipe(gulp.dest('dist/scripts/'));
});// ...
gulp.task('jshint', function() {
//...
gulp.watch([path.source + 'templates/**/*'], ['templates', 'scripts']);
//...
}
The key section in the task:
— read all *.hbs templates
— process thru handlebars() precomilation
— setting the namespace MyApp.templates
— output to a single JS file /dist/scripts/templates.js
- In manifest.json, use handlebars to the project:
{
"dependencies": {
"main.js": {
"bower": [..., "handlebars"],
"files": [
"scripts/main.js"
],
Using
<script type="text/javascript" src=".../dist/scripts/main.js"></script>
<script type="text/javascript" src=".../dist/scripts/templates.js"></script>
Make use include templates.js after main.js