我已经转换了我的这个多皮肤应用程序,以利用 Rails 3.1 中引入的 Assets 管道。在大多数情况下,它出奇的简单,我喜欢预处理能力,它允许您在 CSS/JS 文件中使用内联 Ruby。
不过,我遇到了一个主要问题,尽管链轮功能强大,但似乎很难解决。我的应用程序可以使用在运行时选择的任意数量的皮肤(或“身份”)运行。这个“身份”参数设置诸如缓存目录、数据库连接、 View 路径——以及 Assets 路径之类的东西。虽然所有“身份”都可以有自己的样式表,但也有一个共享的样式表可用于所有实例。所以 Assets 文件夹结构看起来像这样:
在/app/assets/stylesheets/aplication.css.erb 中:
<% require_asset("shared.css") %>
<% require_asset("overrides.css") %>
这会加载两个样式表,并且至关重要的是它使用配置的 Assets 路径来解析它们(这就是为什么我使用 require_assets
而不是标准的 require
和 include
指令,因为它们不会命中解析器)。它返回找到的第一个匹配项,并允许我非常轻松地覆盖部分或全部默认样式。所以/app/assets/stylesheets/shared.css
可以通过在实例 Assets 文件夹中放置一个同名文件来覆盖/app/assets/[identity]/stylesheets/shared.css
如果不存在这样的文件,它会默默地回退到默认的 shared.css。这一切都非常出色 - 我对 JavaScript、图像和字体使用相同的技术,并且在预编译期间所有内容都得到了整齐的处理和打包。但。有一种(横向)继承是我无法实现的;有时一个身份的皮肤与另一个身份非常相似,只有几十行不同(例如,相同的布局但具有不同的配色方案),我真的希望能够做这样的事情:
Assets /样式表/application.css.erb:
<% require_asset("shared.css") %>
<% require_asset("overrides.css") %>
Assets /current_identity/stylesheets/overrides.css:<% require_asset("../../some_other_identity/stylesheets/overrides.css") %>
/* followed by the dozen or so lines that differ for this skin */
...
这失败是因为在当前上下文中“some_other_identity”不在 Assets 路径中 - Rails 在开发模式下找不到该文件,当然在预编译期间也不包含它。如果我确实将它包含在 Assets 路径中,它会加载错误的 overrides.css(只能有一个)。所以我一直在尝试将这样的东西放在 overrides.css 的顶部:<%= File.read(Rails.root.join("app/assets/some_other_identity/stylesheets/overrides.css")) %>
/* rest of CSS */
...
事实上,这正如预期的那样工作。但。因为我现在使用 Assets 管道来为所有 Assets 提供服务,所以我不能再使用固定路径引用 CSS 中的图像 - 我必须使用 <%= asset_path("some_image.png") %>
这样路径解析器就可以发挥它的魔力。这意味着我的 overrides.css
真的是overrides.css.erb
,当然,当你这样做时,ERB 预处理不会发生 File.read()
.所以,我被困住了!帮助!任何人?编辑:如果我使用
<%= ERB.new(File.read(Rails.root.join("app/assets/some_other_identity/stylesheets/overrides.css.erb"))).result %>
它确实尝试解析 ERB,但我得到undefined method `asset_path' for main:Object
这当然是由于我使用 asset_path("some_image.png")
等在我试图包含的文件中。
最佳答案
好的,经过数小时的搜索,我找到了 the list of available helper methods in Sprockets - 如果将其链接到 the Sprockets man page,我会节省很多时间在 GitHub 上(有一个链接,但它指向 #FIXME)。来自链轮 API 文档:
(Object) evaluate(path, options = {})
path
并对文件运行处理器。 <%= evaluate "bar.js" %>
答对了!我将包含指令更改为:
<%= evaluate(Rails.root.join("app/assets/some_other_identity/stylesheets/overrides.css.erb")) %>
并且 CSS 得到处理并插入结果,就像我想要的那样工作。
关于ruby-on-rails - Rails Assets 管道 - 如何包含不在 Assets 路径中的 Assets ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11178518/