Rails with backbone-rails: asset helpers (image_pa

2019-01-21 21:25发布

问题:

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?

回答1:

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.



回答2:

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.



回答3:

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.)



回答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



回答5:

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") %>"/>