So I want to avoid processing JavaScript files with ERB just so I can get a proper asset path to, say, an image.
Currently, this seems like the popular approach:
It depends on the context of where this image is used.
Use Case 1: The image is decorative and needs to be dynamically swapped. Example: Spinner, while data is loading. In this case, I refer to is in my sass and java script.
.spinner
background-image: url(image_path("spinner.png"))
Then I would operate with classes in java script and not images.
$.addClass('spinner')
Use Case 2: Image is part of an object.
There are many situations, when an image actually belongs to a object. In this case, I create a json file, which stores the data and the image reference like this. Then I use erb to unwrap the image reference - my_object.json.erb:
{
"icon" : "<%=image_path("icons/my_icon.png")%>",
"label":"My label",
"description":"My description"
}
Use case 2 requires more work on javascript side to load the json files, but it opens very powerful extensibility options.
Asset pipeline handles both cases famously.
An easier way :
Get the assets prefix in your .js.erb : <%= Rails.configuration.assets.prefix %>. If an absolute path is needed, you can also get the application URL (it's more complicated to get it from rails, so you can just hardcode it in your .js.erb ?)
If you are working with precompiled assets, get the fingerprint of your file which is stored in manifest.yml (at <%= Rails.configuration.assets.manifest %>). The manifest contains a list with all your assets and their respective fingerprints (documentation)
Make assetPath just prepending the application URL + prefix to your image name or fingerprint
An inconvenient is that you have to specify the full image name (included the extension).
Old question, but there is nice way to accomplish this. Just to explain the context of my solution: I need to display markers in a map, which have different possible icons based on the JS dynamic variables. Strangely, using the <%= asset_path('" + somefunction(raw_value) + "') %> was not working. Then, I've looked for the solution bellow.
Concretely, the solution I am using has only one js.erb file which stores the values of the images, and their fingerprinted names, which can be get by a function, image_path
. After that, all my other JS files can be free of the asset_path
and, consequently, of the .erb
Create a file images.js.erb
in your_application/app/assets/javascripts
with the following content:
<%
imgs = {}
Dir.chdir("#{Rails.root}/app/assets/images/") do
imgs = Dir["**"].inject({}) {|h,f| h.merge! f => image_path(f)}
end
%>
window.image_path = function(name) {
return <%= imgs.to_json %>[name];
};
Require this file in your application.js
, which is normally in the same directory as above:
//= require ...
//= require ...
//= require images
//= require_tree .
Then, inside the JS that you've been using <%= asset_path('image.png') %>
, you will use instead image_path('image.png');
Credits to this blog post for posting a Coffee script version from which I've based mine.