Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails with backbone-rails: asset helpers (image_path) in EJS files

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?

like image 836
Jo Liss Avatar asked Nov 29 '11 19:11

Jo Liss


2 Answers

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.

like image 132
carpeliam Avatar answered Oct 09 '22 13:10

carpeliam


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.

like image 25
maxl0rd Avatar answered Oct 09 '22 14:10

maxl0rd