One of the features we love about the Play framework is its out-of-the-box support for dealing with assets: compiling and minifying javascript, CoffeeScript, and LESS stylesheets. This asset compilation is not without issues, for example it is not possible to configure the LESS compiler version, nor can you completely configure the Closure Compiler (though this should be fixed in the next version of play). However, it’s still a great system and we’re sure it will only get better as the play framework matures.
Since we’re using Ember we wanted to tap in to the play asset compilation system to precompile our ember templates on the server before sending them to the client. This has a number of advantages over client-side compilation, allowing us to catch template errors at build time and to eliminate the runtime overhead of template compilation in the client.
The template compiler we created looks at the setting emberEntryPoint, which should be a sequence of directories containing ember templates (note that this is different from the standard asset compilers which have files as entry points, rather than directories). For each entry point directory, we compile all the *.handlebars template files and concatenate them into one javascript file to be served to the browser.
For example, suppose we have the following hierarchy of files:
app/
assets/
templates/
my_view.handlebars
widget/
another_view.hanblebars
We set the emberEntryPoint to app/assets/templates; the compiled template file will be served from /assets/javascripts/templates.pre.js (unminified) or /assets/javascripts/templates.pre.min.js (minified). On the client, after loading this script these templates can be used by simply setting the templateName property on your ember views, for example:
Note that the hierarchy of template files is preserved in the compiled template names, which makes it easy to handle even complicated sets of templates without worrying about name collisions.
To make this all work, we need our asset compiler to do something like the Handlebars precompile script, but running inside rhino as in the standard play asset compilers, and modified to work with the customized version of Handlebars that is embedded in Ember. This requires that we set up the rhino js context so that Ember will run (inspired by this gist), then load the ember library, and finally create our own precompile function to convert the template function objects created by ember to strings. We concatenate these and wrap them with some boilerplate that will add the compiled templates to Ember’s TEMPLATE cache at runtime.
Here’s the code:
We just drop EmberCompiler.scala into the project/ directory in our app, make the necessary modification to our Build.scala script, and play’s build system will pick everything up and start compiling our templates (if you’re already in a play shell you’ll have to tell play to reload to pick up the changes to the build definition). It’s that simple.
We’re looking for excellent engineers to join our team here at NetWallet. So if you are passionate about doing great things with technology, drop us a line. And, if you’re interested in learning more about the technologies we’re using, come to our talks at Silicon Valley CodeCamp on Play and Ember.
#1 by peter hausel (@pk11) on April 25, 2012 - 7:25 pm
Looks cool. Just one comment: I would recommend to turn this into a plugin (the dust plugin could be used as an example: https://github.com/typesafehub/play-plugins/tree/master/dust )
Hope this helps.
Cheers,
Peter
#2 by matthew on April 25, 2012 - 7:37 pm
Hi Peter- That’s absolutely on our todo list. We want to make this usable for the rest of the play community.
#3 by netwallet on April 25, 2012 - 7:40 pm
I actually tried to use the dust plugin as a base for the handlebars one but failed while trying to compile it. Turns that sbt is not simple enough for me or that there’s a spacial thing I need to do it order to get it working.
Would be great to have a readme of how to compile the stuff.
#4 by andyczerwonka on April 26, 2012 - 5:27 am
Curious how Ember fits into your play app?
#5 by matthew on April 26, 2012 - 5:38 am
Ember is a client-side MVC application framework, while play is a server-side web application framework, so in a sense the two are completely independent. But play’s asset compilation helps us handle client-side assets, as the post describes; the combination is working well for us.