Search code examples
ruby-on-railsruby-on-rails-4handlebars.js

Handlebars + Images in Rails 4 - How do I get the right asset_path?


we are using handlebars inside our rails 4 app. The issue that bothers us is that we need to make every single hbs file we have in our system that uses images use a .erb extension so when images pre-compile in production we will have the right asset path....

So instead of completely separating the client side code from server code I need to convert this type of code:

sideBarTemplate.hbs:

<img src="assets/main/logo.png" alt="image description" width="126" height="34">

into this type of code:

sideBarTemplate.hbs.erb:

<img src="<%=asset_path('main/logo.png')%>" alt="image description" width="126" height="34">

Our goal of-course is to find an alternative to rendering server code into our hbs templates as I don't want our front end devs to write "server side code".

Any solutions exist?


Solution

  • You can try injecting a helper both in Ruby (handlebars.register_helper) and JS (Handlebars.registerHelper) that gets a string and prepends the asset root path.

    Something like <img src="{{assetPath 'main/logo.png'}}".

    On the JS side, get time the asset path from Ruby a single time (e.g. with .js.erb) and use that variable in the helper.

    Update:

    Examples on how to use helpers:

    http://jaskokoyn.com/2013/08/08/custom-helpers-handlebars-js-tutorial/ https://github.com/cowboyd/handlebars.rb#block-helpers

    Caveats

    Since asset_path outputs a path that can have a digest it makes things a little bit more complex. Just prepending the asset path won't help when you have digest in the URL.

    Your options:

    • Use https://github.com/alexspeller/non-stupid-digest-assets that will allow also accessing non-digested URLs
    • Or, create a dictionary with all file names as keys and final URL as a value - loop through Rails.root.join("app/assets/**/*.*") and for each path your value is view_context.asset_path(path) and use this dictionary in the JS helper
    • Or, precompile the .hbs and replace the asset paths into the final ones (either by using .hbs.erb or just with a rake task).

    Nothing is perfect but one of the above will get you what you need.