如何根据 Rails 3.1 中的通配符子域将资产搜索路径添加到 Sprockets?
Rails Asset Pipeline 指南 指导您使用 config.assets.paths
在 config/application.rb
中,但目前我无权访问请求的子域。
我希望能够根据请求的子域添加额外的路径(仅适用于当前请求)。
我的应用程序特定详细信息
这是一个基本的 CMS 应用程序。根 domain.com
主机使用标准控制器/视图渲染和默认资源路径来处理管理部分。
对 subdomain.domain.com
的请求会根据 subdomain
呈现站点。它在 before_filter
中调用 prepend_view_path
并为当前添加 Rails.root.join('vendor/sites/[subdomain]/templates')
仅请求。
当请求主机为 [subdomain] 时,我希望能够将
。Rails.root.join('vendor/sites/[subdomain]/assets')
添加到 Sprockets 搜索路径.domain.com
编辑
我最终只是为Sprockets::Environment
添加了一个mixin,它覆盖了调用方法:
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)
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)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
就像您对视图路径所做的那样,添加一个 before 过滤器并将新路径附加到 Rails.application.config.assets.paths
我在观看 Railscasts #279 了解资产管道
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
我同意评论者对您的问题的看法,即“资产管道实际上并不是要根据生产中的每个请求来编译您的资产。” -- 使得实际上不可能完全按照您的要求去做。
那么,有一个替代方案来完成您真正想要完成的任务,即针对不同子域的不同资产解析。将子域特定资产放入资产文件夹的子目录中。
现在,在视图/助手中,当您调用 asset_path 或任何其他采用相对资产路径的助手时,请询问“#{subdomain}/name_of_asset”,而不仅仅是“name_of_asset”。
现在,由于资产编译器的工作方式,此子目录方法可能不起作用,您可能必须将子域放在实际文件名的开头。 “#{子域名}_资产名称”。没有把握。
这仍然不会给你一种“默认失败”的情况,其中某些子域中的某些资产没有特定于子域的资产,它们只是“失败”到默认值。那就太好了。也有可能找到一种方法来做到这一点,但不确定。
但无论如何,遵循这种在显示时使用视图/帮助器中的逻辑请求不同资产的方法......将使您比最初建议的方法更进一步,这可能是不可能的。
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.