ruby-hyperloop / hyper-react

The project has moved to Hyperstack!!
https://hyperstack.org/
MIT License
285 stars 14 forks source link

Access Sprockets assets (images) #236

Open sfcgeorge opened 6 years ago

sfcgeorge commented 6 years ago

It would be great if you could use the Sprockets view method asset_path in Hyperloop components.

Here is one way to do it. Add this file (and make sure it is required in your Sprockets JS manifest):

app/assets/javascripts/asset_path.js.erb

<%
  # Alternatively there's a gem to do all this but seems over complicated
  # https://github.com/izaurio/js_assets

  asset_paths = {}
  Rails.application.assets.each_file do |path| 
    if path =~ %r{/app/assets/images} # alter to suit your needs
      asset = Rails.application.assets.find_asset(path)
      asset_paths[asset.logical_path] = asset.digest_path 
    end
  end

  assets_host = Rails.application.config.action_controller.asset_host
  assets_host = "/" unless assets_host.present?
  assets_root = File.join(assets_host, Rails.application.config.assets.prefix)
%>

(function () {
  var asset_paths = <%= asset_paths.to_json %>;
  var assets_root = <%= assets_root.to_json %>;

  window.asset_path = function(logical_path) {
    return assets_root + "/" + asset_paths[logical_path];
  };
})();

You can either call the above JavaScript method via backticks, or add a nicer Opal method in your ApplicationComponent #227:

app/hyperloop/components/application_component.rb

class ApplicationComponent < Hyperloop::Component
  def asset_path(logical_path)
    `asset_path(#{logical_path})`
  end
end

Inherit from ApplicationComponent and use the method in your components:

class Logo < ApplicationComponent
  render do
    IMG(src: asset_path("logo.png")) {}
  end
end
catmando commented 6 years ago

Really nice...

I propose we add a config switch Hyperloop.config.visible_assets that is assigned either nil, (none), true (all) a pattern (which must match) , an array of strings (subdirectories of app/assets/ to match) or a proc (which will return truthy/falsy values)

Hyperloop.configuration do |config|
  config.visible_assets = %r{/app/assets/images} # or
  config.visible_assets = true # everything!
  config.visible_assets = false # nothing
  config.visible_assets = ['app/assets/images', 'app/assets/funky']
  config.visible_assets = lambda { |file| file =~ %r{/app/assets/images/*.png} }
end

Too many options?

catmando commented 6 years ago

I just looked at https://github.com/izaurio/js_assets

why not just use that? You said it was complicated... do you mean internally. The API looks straight forward.

sfcgeorge commented 6 years ago

Yeah internally complicated and possibly unmaintained. But the API is perfect. Hyperloop could wrap it in a thin abstraction layer then if it ever breaks it can be swapped out invisibly.

On 5 Jan 2018, at 19:06, Mitch VanDuyn notifications@github.com wrote:

I just looked at https://github.com/izaurio/js_assets

why not just use that? You said it was complicated... do you mean internally. The API looks straight forward.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or mute the thread.