6

我已经转换了我的这个多皮肤应用程序,以利用 Rails 3.1 中引入的资产管道。在大多数情况下,它非常简单,我爱上了预处理能力,它允许您在 CSS/JS 文件中使用内联 Ruby。

不过,我遇到了一个大问题,尽管 Sprockets 的强大功能似乎很难解决。我的应用程序可以使用在运行时选择的任意数量的皮肤(或“身份”)运行。这个“身份”参数设置了缓存目录、数据库连接、视图路径——实际上还有资产路径。虽然所有“身份”都可以拥有自己的样式表,但也有一个共享的样式表,用于所有实例。所以资产文件夹结构看起来像这样:

在 /app/assets/stylesheets/aplication.css.erb 中:

<% require_asset("shared.css") %>
<% require_asset("overrides.css") %>

这会加载两个样式表,关键是它使用配置的资产路径来解析它们(这就是我使用require_assets而不是标准requireinclude指令的原因,因为它们不会命中解析器)。它返回找到的第一个匹配项,并允许我非常轻松地覆盖部分或全部默认样式。所以

/app/assets/stylesheets/shared.css

可以通过在实例资产文件夹中放置同名文件来覆盖

/app/assets/[identity]/stylesheets/shared.css

如果不存在这样的文件,它会默默地回退到默认的 shared.css。

这一切都非常出色——我对 JavaScript、图像和字体使用了相同的技术,并且在预编译期间一切都得到了整齐的处理和打包。但。有一种我无法实现的(横向)继承;有时一个身份的皮肤与另一个身份非常相似,只有几十行不同(例如相同的布局但具有不同的配色方案),我真的希望能够做这样的事情:

资产/样式表/application.css.erb:

<% require_asset("shared.css") %>
<% require_asset("overrides.css") %>

资产/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”不在资产路径中 - Rails 在开发模式下找不到文件,当然它也不包含在预编译期间。如果我确实将它包含在资产路径中,它会加载错误的 overrides.css (只能有一个)。所以我一直在尝试把这样的东西放在 overrides.css 的顶部:

<%= File.read(Rails.root.join("app/assets/some_other_identity/stylesheets/overrides.css")) %>
/* rest of CSS */
...

事实上,这正如预期的那样有效。但。因为我现在使用资产管道来提供所有资产,所以我不能再使用固定路径引用 CSS 中的图像 - 我必须使用<%= asset_path("some_image.png") %>这样的路径解析器才能发挥其魔力。这意味着 myoverrides.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")在我试图包含的文件中使用了 etc 。

4

1 回答 1

5

好的,经过数小时的搜索,我发现了Sprockets 中可用的辅助方法列表——如果从 GitHub 上的 Sprockets 手册页链接到它,我会节省很多时间(有一个链接,但它指向 #整我)。来自 Sprockets API 文档:

  • (Object) evaluate(path, options = {})
  • 在文件上读取path和运行处理器。
  • 这使您可以捕获资产的结果并将其直接包含在另一个中。
  • <%= evaluate "bar.js" %>

答对了!我将包含指令更改为:

<%= evaluate(Rails.root.join("app/assets/some_other_identity/stylesheets/overrides.css.erb")) %>

并且 CSS 得到处理并插入结果,就像我希望它工作的方式一样。

于 2012-06-24T18:41:10.300 回答