Saturday, November 30, 2013

How to split ember handlebar templates into multiple files using node and grunt

Recently, I was working on a project which used EmberJs.  At the time of writing this post, EmberJs does not provide a way to split the Handlebar templates into multiple files.

This is OK to being with, but soon enough for a decently complex application, keeping all Views in one template files is just not maintainable.  Soon, I was hunting for a way to split the handlebar templates into multiple files to better maintain and manage them.

My search let me to various blogs and a lot of scattered information.  Eventually I was able to find a decent solution for my problem.  In this post, I am going to demonstrate how exactly to solve this problem, in the hope that someone else would benefit from my findings.

How do they do it!

To split the handlebar templates into multiple files, I took help of nodejs and an awesome node module called Grunt.  Here are the steps I followed to get the job done.

Installation

  • I am going to assume that you already have npm and nodejs installed on your machine.  If you don't then, please follow the steps mentioned in this link to get them. 
  • Next step, is to get the package.json file which can be used by nodejs.
  • To create a package.json file use the following command.  It will ask some basic questions - please answer them. 

  • This should create a default package.json file which can be used as a foundation for what we want to achieve
  • Next thing we need to do is install a nodejs module called grunt.  This is an awesome task runner which has hundreds of plugins that help us perform  repetitive tasks like minification, compilation, unit testing, linting, etc.
  • The Grunt ecosystem is huge and it's growing every day.  You can use Grunt to automate just about anything with a minimum of effort.
  • To make Grunt work for us, we need to install grunt, grunt-cli, grunt-ember-templates and grunt-contrib-watch node modules.  Install them using the following command.    

  • The grunt-ember-templates module will be used to pre-compile the handlebar templates.
  • The output of this plugin would be a templates.js file which will hold all pre-complied templates.  This can then be easily included in the EmberJs application.
  • The grunt-contrib-watch module exposes a task called watch.  This task can keep an eye on the file system for any changes and invoke the grunt-ember-templates task to recompile the handlebar templates and regenerate the templates.js.  Don't worry if you don't get it at this point.  But trust me, its extremely convenient to have the watch task especially during development.
  • These are all the modules we will need to get the job done.
Creating the Gruntfile.js
  • For Grunt to do its job, it needs to know about the job at hand.
  • We need to inform Grunt about what is to be done, we do this using a file called Gruntfile.js
  • The contents of Gruntfile.js would look as follows

  • This file basically sets up two tasks called emberTemplates and watch.
  • emberTemplates - tasks compiles all handlebar templates (*.hbs files) stored under templates/ directory (and all its sub-directories) and generates a file called templates.js inside the build directory.
  • As explained earlier watch task keeps an eye on the file system modifications to any of the handlebar templates (*.hbs) files.  If these files have been modified then it invokes the emberTemplates task to recompile the handlebar templates and regenerate the templates.js file.
  • The default task for this Gruntfile.js is emberTemplates
  • Let's say we have two template files, index.hbs and login.hbs, their contents are as follows


Light's, Camera, Action!
  • All that is left to do is invoking the grunt command from the command line.

  • This will compile the handlebar templates and generate the templates.js file.  
  • All the handlebar templates are already registered with EmberJs and are ready to be included in an EmberJs application.  
  • The name by which they are registered with EmberJs is same as the name of the file that holds the template.

  • When we doing the development we keep editing the handlebar templates quite often.
  • After we edit them we have to run grunt command again to regenerate the templates.js file.  But as promised earlier we will let watch task do it for us.
  • Run the following command on the command line.

  • This command will never return, it will keep an eye on any changes to the hbs files.
  • Let's update the login.hbs template as follows

  • Since the watch task is already running, it detects the change in the login.hbs and regenerates the templates.js.
  • The idea is to keep that command prompt always running and continue editing the handlebar templates, the templates.js will be seamlessly generated and kept updated for us!
  • Updated templates.js looks as follows.

Isn't this awesome!  We got our modularity and the ease of development, its like have your cake and eat it too!

Well that's all folks, until we meet again, have fun! 
Have some Fun!