13

The Rails Asset Pipeline guide instructs you to use config.assets.paths in config/application.rb but I don't have access to the request's subdomain at this point.

I'd like to be able to prepend an extra path (for the current request only) based on the request's subdomain.

My application specific details

It's a basic CMS app. The root domain.com host handles the administrative part with standard controller/view rendering and default asset paths.

Requests to subdomain.domain.com renders the site based on subdomain. It calls prepend_view_path in a before_filter and adds Rails.root.join('vendor/sites/[subdomain]/templates') for the current request only.

I'd like to be able to prepend Rails.root.join('vendor/sites/[subdomain]/assets') to the Sprockets search paths when the request host is [subdomain].domain.com.

EDIT

I ended up just dropping in a mixin for Sprockets::Environment that overwrites the call method:

module SiteAssetsResolver
  def call(env)
    begin
      # prepend path based on subdomain (from env)
      super # Sprockets::Server#call
    ensure
      # remove path based on subdomain
    end
  end
end

MyApp::Application.assets.extend(SiteAssetsResolver)
Sean Huber
  • 640
  • 4
  • 7
  • 1
    The asset pipeline isn't really meant to be compiling your assets each request in production. It's great for development but you should compile them to static files for production. Thus you'll need to develop you own system for this (perhaps a controller that serves CSS files?) or build your apps separately. – thomasfedb Sep 26 '11 at 14:35

2 Answers2

1

Just as you did for your view path, add a before filter and append the new path to Rails.application.config.assets.paths

I got this idea while watching Railscasts #279 Understanding the Asset Pipeline

pedz
  • 2,271
  • 1
  • 17
  • 20
  • 2
    Hmm, pretty sure changing Rails.application.config.assets.paths will add the path on for the WHOLE application, permanently, not just for the current request. It's kind of right there in the call you are making to Rails.application. AS opposed to prepend_view_paths, which is documented to effect the current request only. So the OP question is if there's something similar you can do for asset_paths... but Rails.application ain't it. It's possible looking at the code for prepend_view_paths could give you an idea of how to hack it in yourself though. – jrochkind Sep 30 '11 at 12:55
1

I agree with commenter on your question that said "The asset pipeline isn't really meant to be compiling your assets each request in production." -- making it not really possible to do exactly what you ask.

So how about an alternative to accomplish what you're really trying to accomplish here, which is different asset resolution for different subdomains. Put your sub-domain specific assets in sub-directories of your asset folders.

Now, in the view/helpers, when you call asset_path or any other helpers that take a relative asset path, ask it for "#{subdomain}/name_of_asset" instead of just "name_of_asset".

Now, because of the way the asset compiler works, it's possible this subdirectory method won't work, you may have to put the subdomain at the beginning of the actual filename instead. "#{subdomain}_name_of_asset". Not sure.

And this still wouldn't give you a sort of 'default fall through' where some assets in some subdomains don't have subdomain-specific assets, they just 'fall through' to the default. Which would be nice. It's possible a way can be figured out to do that too, not sure.

But at any rate, following this approach of asking for a different asset at display-time using logic in view/helper.... is going to get you further than your original suggested approach, which probably isn't possible.

jrochkind
  • 22,799
  • 12
  • 59
  • 74