ruby-on-rails - Rails Assets 管道 - 如何包含不在 Assets 路径中的 Assets ?

标签 ruby-on-rails asset-pipeline erb

我已经转换了我的这个多皮肤应用程序,以利用 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 而不是标准的 requireinclude 指令,因为它们不会命中解析器)。它返回找到的第一个匹配项,并允许我非常轻松地覆盖部分或全部默认样式。所以
/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并对文件运行处理器。
  • 这允许您捕获 Assets 的结果并将其直接包含在另一个 Assets 中。
  • <%= 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/

    相关文章:

    ruby-on-rails - 多态评论,评论验证失败时如何渲染?

    ruby-on-rails - 如何在rails中为rake任务编写单元测试用例?

    ruby-on-rails-4 - Rails 4、@font-face、sass、 Assets ?

    ruby-on-rails - rails开发环境循环依赖报错

    css - 如何让图像与 Bootstrap 导航列表中的文本对齐?

    javascript - 如何动态创建包含类属性的列表

    ruby-on-rails - 使用 Prawn 从 Base64 生成带有图像的 PDF

    ruby-on-rails - ruby/rails NoMethodError?使用自定义验证方法时

    ruby-on-rails-3 - 使 Assets 管道像开发中的生产一样

    javascript - 使用 Rails 检查是否启用了 Javascript(服务器端)