Rails 3.1 JavaScript templating with Sprockets
I have been using Rails 3.1 for a few weeks now, and have grown to love
the changes that have been made. Sprockets 2 has changed my workflow in
a lot of ways, and has been a solid improvement as far as rapid
development is concerned. However, with Quick Left's commitment to the
bleeding edge of front end development, we need JS templating - something
Sprockets currently doesn't have support for.
The Problem
Sprockets 2 does not currently support templates, something that will be
fixed in the future. Without templating, it's difficult to take
advantage of Rails 3.1 for front end templating, forcing us back to
other methods for templating - and losing some of the organizational
advantages gained in the process.
Understanding Sprockets and Tilt
Sprockets is a gem that
has been around for a while. Sprockets automatically combines and serves
assets from a mounted route inside the app/assets directory - allowing
for greater code organization. Tilt
is even cooler - it acts as a generic interface to many markup and
markdown engines. Because of this, I wanted my templates
to be in Haml, without any extra effort.
Tilt also allows for chaining extensions. Keep this in mind.
Testability
I started out with an RSpec example of how I thought this thing
should work:
This is extremely simple - and I created a very simple haml file in
/spec/support for this purpose:
Looks good. Our spec fails for a lot of reasons, but let's continue.
Building out a Module
From there, I built out a pretty simple module. I create a new Tilt
object, and render it. However, I need it as a string, since it will
eventually be in a JS file, and I need to strip newlines. From what I
discovered with Rails, Tilt will render out as an ActiveSupport::SafeBuffer
object, which overwrote the to_s method. Therefore, inspect was needed
to force it in String format.
I abstracted out build_file so there was a clean way to accept
extensions and relative paths. With this, our spec passes, but we still
need this as a JS template.
Template files
From here, I created a templates directory in app/views, and created
some Haml files in there. Sprockets expects javascripts to be in
app/javascripts, so I created templates.js.coffee. The only problem is
that we can't execute Ruby from inside this file.
Tilt to the Rescue
As I mentioned before, Tilt allows us to chain file extensions, so I renamed my file to
templates.js.coffee.erb, which looks like this:
From here I create a window.JST object, which has a bunch of keys inside
corresponding to rendered Templater templates. Easy, clean, and gives us
the desired outcome.
From here, we have templating in Sprockets 2!
Other Cool Tricks
While templates are awesome, it's not the only place we can use erb.
Rename any coffeescript file to .js.coffee.erb, and you can do things
like:
- Embed environment variables in. Useful for API keys, etc.
- Use markdown or textile for other templates.
- Abstract out parts of your front end application to Rails helpers
- And more!
Let us know if you can think of other applications in the comments.
Template on!