12

I have a Rails 3.1 app that uses the codebrew/backbone-rails. In a .jst.ejs template, I would like to include an image, like so:

<img src="<%= image_path("foo.png") %>"/>

But of course the asset helpers are not available in JavaScript.

Chaining ERB (.jst.ejs.erb) does not work, because the EJS syntax conflicts with ERB.

Here is what I know:

  • The asset helpers are not available in the browser, so I need to run them on the server side.
  • I can work around the problem by making the server dump various asset paths into the HTML (through data attributes or <script> and JSON) and reading them back in JS, but this seems rather kludgy.

Is there a way to somehow use the asset helpers in EJS files?

Jo Liss
  • 30,333
  • 19
  • 121
  • 170
  • You can also redefine the ejs tags (if they really are a port of Underscore's templating function as suggested in the ruby-ejs gem docs) with `_.templateSettings` [underscore.js template function](http://documentcloud.github.com/underscore/#template), thus allowing you to use `{{ code }}` or some other tagging of your choosing – wulftone Jan 26 '12 at 19:48

5 Answers5

25

There is a way, actually, to chain a .jst.ejs.erb file, although it's fairly undocumented, and I only found it through looking at the EJS test cases. You can tell EJS to use {{ }} (or [% %] or whatever else you want) instead of <% %>, and then ERB won't try to evaluate your EJS calls.

Make sure to require EJS somewhere in your code (I just included gem 'ejs' in my Gemfile), and then create an initializer (I called it ejs.rb) that includes the following:

EJS.evaluation_pattern    = /\{\{([\s\S]+?)\}\}/
EJS.interpolation_pattern = /\{\{=([\s\S]+?)\}\}/

Then just make sure to rename your templates to .jst.ejs.erb, and replace your existing <% %> EJS-interpreted code with {{ }}. If you want to use something other than {{ }}, change the regular expressions in the initializer.

I wish there were an option in Sprockets to handle this through the config rather than having to explicitly include EJS, but as of the moment, there's no way to do that that I know of.

carpeliam
  • 6,691
  • 2
  • 38
  • 42
  • hmm this does not work for me, yes i restarted rails. it simply ignores the option and continues to work with the default evaluation/interpolation – zanedev Jan 16 '13 at 05:20
  • @zanedev where did you put the option? can you create a gist? – carpeliam Jan 17 '13 at 16:47
  • I followed the instructions exactly, created a ejs.rb file in the initializers for the rails project and restarted, just seems to ignore the setting. i dont have the code any more as we have went a different direction now. could have been some other issue with my environment i suppose i wouldnt worry about it unless other people show up with the same result – zanedev Feb 03 '13 at 20:13
16

I can see two ways. Neither are great.

When you say <%%= variable %> then this is rendered by ERB as <%= variable %>, so you could double percent escape everything but the asset_tags and that would survive the trip through one ERB pass on the way to EJS.

If you find that too gross...

How about making a different javascript file, with an ERB extension, that defines your asset paths? And then use the asset pipeline to require that.

So say assets.js.erb defines something like:

MyAssets = {
  'foo': <%= image_path("foo.png") %>,
  ...
}

And then require this somewhere near the top of your manifest. And then reference the globals however that works in EJS.

maxl0rd
  • 1,446
  • 8
  • 11
5

For those willing to try HAML instead of EJS: Using haml-coffee through haml_coffee_assets has worked well for me as well.

You can have the following in a .hamlc.erb file:

%img(src="<%= image_path('foo.png') %>")

(It still doesn't give you routing helpers though, only asset helpers.)

Jo Liss
  • 30,333
  • 19
  • 121
  • 170
4

Ryan Fitzgerald was kind enough to post a gist of his JavaScript asset helpers (which get precompiled with ERB): https://gist.github.com/1406349

Jo Liss
  • 30,333
  • 19
  • 121
  • 170
2

You can use corresponding Javascript helper via the following gem: https://github.com/kavkaz/js_assets

Finally (after installing and configuring) you will be able to use it like this:

<img src="<%= asset_path("foo.png") %>"/>
wik
  • 2,462
  • 1
  • 24
  • 29