I am having a problem with Handlebars compiled templates. I feel like I am completely missing something important, but try as I might, I can't seem to work it out, or find any information online as to why this particular situation is presenting itself.
I am compiling using a Gulp task using gulp-handlebars. The gulp task is:
gulp.task('build-hbs', function(){
gulp.src('root/app/src/hbs/*.hbs')
.pipe(handlebars())
.on('error', notify.onError({
message: 'Error: <%= error.message %>'
}))
.pipe(declare({
namespace: 'Handlebars.templates',
noRedeclare: true // Avoid duplicate declarations
}))
.pipe(concat('templates.js'))
.pipe(gulp.dest('root/app/js/templates/'));
});
for simple templates things are working OK, however I am now trying to use a simple helper (Note: when working with non-compiled templates, the helper works fine). The helper is:
Handlebars.registerHelper('gravatar', function(hash, size) {
var grav = '<img src="http://www.gravatar.com/avatar/' + hash + '.jpg?r=g&d=mm&s=' + size + '">';
return new Handlebars.SafeString(grav);
});
The template itself looks like this:
<div id="nick"><b>{{display}}</b></div>
<div id="image">{{gravatar hash}}</div>
Once compiled, I get:
this["Handlebars"] = this["Handlebars"] || {};
this["Handlebars"]["templates"] = this["Handlebars"]["templates"] || {};
this["Handlebars"]["templates"]["profile"] = {"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
var helper, alias1=helpers.helperMissing, alias2="function", alias3=this.escapeExpression;
return "<div id=\"nick\">\r\n <b>"
+ alias3(((helper = (helper = helpers.display || (depth0 != null ? depth0.display : depth0)) != null ? helper : alias1),(typeof helper === alias2 ? helper.call(depth0,{"name":"display","hash":{},"data":data}) : helper)))
+ "</b>\r\n</div>\r\n<div id=\"image\">\r\n <img src=\"http://www.gravatar.com/avatar/"
+ alias3(((helper = (helper = helpers.hash || (depth0 != null ? depth0.hash : depth0)) != null ? helper : alias1),(typeof helper === alias2 ? helper.call(depth0,{"name":"hash","hash":{},"data":data}) : helper)))
+ "?s=32\">\r\n</div>";
},"useData":true};
Within my JS code, I do something like:
$('#profile').html(Handlebars.templates.profile({
display:'user 1',
hash:'abdcef....'
}));
When I run the code I get the error:
TypeError: Cannot read property 'helperMissing' of undefined
Which relates to the compiled template code:
...
var helper, alias1=helpers.helperMissing, alias2="function", alias3=this.escapeExpression;
...
I can't seem to find any reason for this code to be added, or any reference to the helperMissing
function in the Handlebars documentation...
Any insights in to why this might be happening would be extremely welcome!
In the end, the problem turned out to be one of conflicting versions!
The way I ended up fixing it was to change the gulp file a little:
The main difference is that is specifically loads the version of handlebars installed by
npm
to use as the compiler.The second job copies the handlebars.runtime.js file from the node_modules folder in to the folder where the browser will actually pick it up. This guarantees compatibility!
The
wrap
anddeclare
calls are required to make sure the compiled code is actually correct (which is different from the information on the handlebars site - thegulp-handlebars
module just works in a slightly odd way).Finally the
insert
adds a require call to make sure it works in a stand-alone manner to ensure theHandlebars
dependency is met at runtime.Finally, there was an error in my template which should have read:
the missing second parameter to the
gravatar
helper caused an error - this only presented itself once the compiled templates were working but was easy to spot at this point!