So, I'm not sure I can say why I'm playing with Handlebars today (just asked if I could talk about it), but I ran into an interesting issue with it today that I thought I'd share.
Handlebars supports precompilation of templates. This makes your application run a bit quicker by skipping the template compilation phase. It's done via a simple CLI program you can install via npm.
Handlebars also supports partials. These are templates that are meant to be included in other templates. Oddly, the Handlebars site doesn't document this feature. (To be clear, it mentions the API for it, but doesn't describe it as a feature.) If you go to the Github repo for Handlebars though it is fully documented.
Ok, so the normal way to compile templates is like so:
handlebars file.handlebars file2.handlebars -f templates.js
This takes two files, file.handlebars and file2.handlebars, and compiles it into one file, templates.js. Once you've done that, and included the file, you can access the template function like so:
rendered = Handlebars.templates.file(data here);
The file name, minus the extension, becomes the name of the template function. As an FYI, you should name your files with the .handlebars extension. If you don't, then the full file name becomes the name of the template function. If I had used file.html as my filename, then my template function would be file.html, and who knows what grief that dot would have caused.
Ok, so to handle partials, you have to pass a flag, -p:
handlebars mypartial.handlebars -p -f partials.js
As before, the name of the file dictates how you would use it. If I had used the file name from the code snippet above, I could include a partial like so: {{> mypartial}}. As before, ensure you use the handlebars file extension. I had used .partial to help keep things organized and ran into the issue with the name being mypartial.partial instead of just mypartial.
Ok, so finally, the tip. As far as I know, there is no way to compile 'regular' templates and partials in one call. So to create my compiled templates and partials and store them in one file, I've ended up doing this:
handlebars file1.handlebars file2.handlebars file3.handlebars -f templates.js
handelbars file10.handlebars file11.handlers -p -f partials.js
cat templates.js partials.js > templates_all.js
The handlebars CLI supports globs which means I could have used *.handlebars, but since I had my templates and partials in one folder, that wouldn't have worked. And obviously you could automate this with a simple Grunt script as well.
It is certainly possible that I'm wrong about the need to do this in multiple calls. I opened a ticket over on the Handlebars site to request this feature and if I'm missing the obvious, I'll update the blog entry. (And part of me hopes that I'm wrong and this entire blog entry is a waste. :)
Archived Comments
As an FYI, the project creator already said no to my ticket, so, this post is useful I guess.
Thanks for writing such information.. That's exactly what I was looking for!
Nice Article!!. could you please let me know to register precompiled partials. I try like Handlebars.registerPartial("partialname", 'partial.js'). But not working.
What if you drop the .js?
This really solves my problem. Thanks a lot Raymond.
Handlebars.registerPartial("partialName", Handlebars.partials['partial']);
Thank you for posting this! This saved me a lot of hair-tearing. I made an npm script to automate this precompilation process, which all in all has made my first Handlebars experience much more pleasant than it was starting to become.
You are most welcome.
Thx for the article.
I have a question, how precompilation can work with partials? Do you have try once?
I try to find a way to make it works but when you put the partial syntax into your main template, you can't compile anymore..
Thx for the answer!
I describe how to work with them in the post above. Did you see it?
Yes i see it, but it doesn't work when I try it.. Then i found a solution.
Thx for the answer Raymond !
Cool - so is it something i got wrong, or did it change in Handlebars? (This blog entry is almost two years old.)
No everything you say is right! In fact, I had another error in my template which crash my compilation but it was on exact same place of my partial declaration.
So I thought it was my partial ^^
Thx for your article, very helpful!
Glad to hear it. As an FYI, I have a book, and video series, on client-side templating. You can buy it via the "About" link above. Or not. It's all good. ;)