Update: Sails 0.12+ ships with Handlebars support out of the box. You just need to pass in the --viewEngine
option when generating a new Sails App. So don’t worry about anything written below. Just do something like this:
sails new myApp --viewEngine handlebars
The information below is just for posterity. 🙂
The Problem
I like SailsJS. I’ve been using it for a pet project recently and it’s a great way to create all the boilerplate for a webserver. I definitely prefer it over starting an ExpressJS server from scratch.
Sails has a lot of pros. I love the model/controller scaffolding, Waterline, using middleware as policies, and enforcing API-driven development. However, I’m a big fan of Handlebars and I really don’t like EJS so I thought that was going to be a blocker for me.
Fortunately, I have a little hack which lets me use Handlebars with Sails. Before starting down this path, I took a look at the StackOverflow answers on how to get SailsJS working with Handlebars. None of the replies seemed suitable to me. Most require you to pass in your layout
and partials
properties to every res.view()
call. There isn’t much information on using Handlebars Helpers either. What I wanted was to just do this:
res.view();
And I want it to pull the correct layout and all the available partials. I also want it to be able to read in the correct Handlebars Helpers. All the benefits that Sails + EJS gives you, except using Handlebars instead.
The Solution
The solution was hidden inside Christopher Pappas’ closed pull request. I used his code to modify Sails Core to use express3-handlebars
. If you want to use Handlebars as your view engine, modify your config/views.js
to this:
module.exports = {
engine: 'handlebars',
layout: 'main.handlebars', //whatever your default layout is
helpers: require('./helpers') //pull in your helpers (I store it in config/helpers.js)
}
Here’s how you should structure your views/
directory:
views/
layouts/
main.handlebars
partials/
partial1.handlebars
partial2.handlebars
controller1/
action1.handlebars
action2.handlebars
All the partials within the root partials/
directory will be available for use in any view.
Installation
Remember that this is a hack that has only been tested in Sails 0.9.9. Sails 0.10+ introduces some changes to how view engines are created, so this code won’t work there as-is, but it shouldn’t be hard to port over.
In terms of installation, I am pulling in Sails from my Handlebars branch. Here’s what my package.json
looks like:
//within package.json
"sails": "git://github.com/tilomitra/sails.git#handlebars"
Then, instead of installing Sails globally via npm -g install sails
, I install it locally via npm install sails
. This pulls in my Handlebars-enabled version of Sails from GitHub.
I know this isn’t acceptable for a lot of people, but it did the job for me. One notable flaw is the inability to update as Sails updates. However, the only file that I modified was hooks/views/index.js
, so it’s not hard to port it over. I will be trying out Sails 0.10.x eventually because it has support for model associations (something which I badly need), so I’ll post an update to this post if I am able to get Handlebars working with Sails 0.10.x.
Happy Coding!
Credit to Christopher Pappas who wrote the original code that made this possible, and to Balderdash for creating Sails.
hi, thanks for this man ! I do not want to use the cluttery EJS templating.. 😀
i am trying to do this fix on v0.10 because it has some nice things .. did you ever succeed and is it up somewhere or your github repo ?
https://github.com/koraysels/sails/tree/v0.10
i added handlebars support thanks to you in v0.10 ! also adde sails-generate-views-handlebars for easy setup 😀
Awesome work! Thanks!
Thanks for he post, I also would like to use handlebars badly but I got into a lot of issues trying by myself and couldn’t use layouts at all, which is such basic feature that I cannot work without it.
I didn’t try your solution for two reasons:
– Since March, the v0.10 hs been released and I would like to jump into it, so I cannot use this solution. Did you find any workaround for the new sails version?
– Can you use the partials from the server and the client side? Something I LOVED in ejs+sails is that the partials where available from the client, which makes things potentially much better. It is obvious that’s usable from the server here, but what about the client? Does the same partial are somehow available from the browser?
I also hate EJS, I don’t like the syntax and the project died a few months ago (github), someone else is now maintaining it, but anyway I wasn’t able to use partials from the server side with sails…
I gotta update this for v0.10. Once I get back to SailsJS land, I’ll be sure to do this. Re. using partials on the client and server, yes this is possible. I’ll update my Node Boilerplate on GitHub with that code. Contact me via email to learn more about this!
Many Thanks, I really love handlebars, no I can try and develop something with Sails.