将特定于页面的CSS添加到Rails Asset Pipeline

Kev*_*ica 17 ruby-on-rails asset-pipeline

这是几个人之前提出过的一个问题,但没有一个问题是以我认为有用的方式得到解答或回答的,所以我写的问题和答案我觉得有帮助.


我有一个使用资产管道的Rails 3.1+应用程序.我想要使​​用不同的CSS有一个特定的操作.(在我的具体情况下,我有一个打算打印的页面,所以它真的需要完全不同的CSS,不需要任何Javascript.)目前,我只有一个特定于应用程序的CSS文件.如何添加新的CSS文件并指示资产管道使用我的文件?

例如,现在,我的app/assets样子

app/assets
    /javascript
        application.js
        custom.js.coffee
    /css
        application.css
        custom.css.scss
Run Code Online (Sandbox Code Playgroud)

我想添加print.css一个特定操作视图使用的文件.此视图不会使用该application.css文件.我该如何添加print.css

Kev*_*ica 26

我发现这篇博文非常有帮助:http://blog.seancarpenter.net/2012/11/05/page-specific-javascript-with-the-asset-pipeline/.我的回答解释了这位博主已经写过的内容,并填写了一些遗漏的细节.


首先,您必须阅读并理解资产管道的Rails指南.遗憾的是,本指南并未明确说明如何添加特定于操作的资产,但它确实涵盖了您需要了解的一些概念.确保你理解这些想法:

  • 资产管道编译Javascript,CSS和其他资产,以便Rails服务器可以缓存资产以获得更好的性能.
  • 该清单文件使用类似的命令require,require_tree以及require_self指示哪些文件被编译到一起.
  • 为了使资产管道在生产中正常工作,您需要手动运行rake assets:precompile以在public目录中生成已编译的缩小资产.

这些想法是关于资产管道的最低"需要知道"信息.如果你还没有理解这些想法,那么你就没有关于管道的"专家或发烧友"级别的知识,不幸的是,SO并不是学习这些东西的合适场所.幸运的是,资产管道的Rails指南只需 15分钟的阅读时间,如果您需要,可以让您快速上手.


其次,这些是您需要进行的更改,以确保资产管道正确查看和处理您的新print.css文件.

跟着这些步骤:

  1. print.css文件添加到app/assets/css.
  2. 您需要创建一个清单文件,显示Rails在哪里找到print.css.您需要这样做,即使您只添加了一个CSS文件.这是一个简单的步骤:
    • 添加一个名为print.jsapp/assets/javascript.
    • 将此行添加到print.js:
//= require print

这将是整个print.js文件中唯一的一行.如果我理解正确,Rails希望清单文件具有文件扩展名.js,这就是我们不使用print.css清单文件的原因.

  1. 我们现在需要指示Rails查找并使用print.js清单.在config/application.rb文件中添加以下行:
config.assets.precompile += %w( print.js )
  1. 我们差不多完成了!但是,已存在的application.js清单包括该行//= require_tree .,这意味着它将包含您的print.css文件.这将导致您的print.css样式影响整个网站,而不仅仅是单个视图.有两种方法可以解决这个问题:
    • 如果application.jsprint.js不共享任何资产,您可以使用您的stub命令application.js来排除使用的资产print.js.这样做是指示从其自己的引用文件列表中application.js删除任何print.js引用的资产.我们的修改application.js看起来像:
(snip...)
require_tree .
stub print

有关更多信息,请参阅此答案.

  • 如果您print.jsapplication.js文件共享某些资产,则需要将所有使用的资产移动application.js到子目录中.我自己没有这样做,所以我不是这方面最有帮助的.看看这个答案的说明.

现在我们已经包含print.css在资产管道中.我们现在需要指导Rails print.css在您的特定视图中使用.

假设您的操作位于reports控制器中,并且操作已命名print_reports.这意味着我们有一个reports_controller.rb文件和一个print_reports.html.erb(或.haml)文件.我们需要对这些文件进行一些更改.

  1. 首先,添加新布局app/views/layouts.也许叫它print.html.erb.我们将为您的print_reports.html.erb文件使用这种新布局.根据需要进行设置.对于要打印的页面,这可能非常简单,例如
<html>
    <head>
        <title="Print">
    </head>
    <body>
        <%= yield %>
    </body>
</html>

使用单独的布局的缺点是难以保持此布局和应用程序其余部分使用的布局同步,但如果您使用单独的CSS文件进行操作,则不太可能希望布局相同.

  1. stylesheet_link_tag在布局的标题中添加一个指向您的标题print.css:
<html>
    <head>
        <title="Print"/>
        <%= stylesheet_link_tag "print" %>
    </head>
    <body>
        <%= yield %>
    </body>
</html>
  1. 在控制器中,我们将告诉Rails使用我们的新布局进行操作.将行添加layout 'print', only: [:print_reports]到您的控制器:
class reports_controller < ApplicationController
    layout 'print', only: [:print_reports]

    #snip

有关更多信息和一些不同的方法,请参阅此问题.

此时,当您运行该应用程序时,您的print_reports操作应该print.css正确使用!


记得rake assets:precompile在部署到服务器之前运行.

  • 您实际上不需要添加额外的JavaScript文件.只需在config/application.rb中输入`config.assets.precompile + =%w(print.css)`,然后像往常那样预编译资产. (7认同)

Bij*_*jan 5

官方解决方案

它记录在官方 Rails 指南中:http://guides.rubyonrails.org/asset_pipeline.html#controller-specific-assets

实际上,您可以省略 require_tree 指令(位于application.cssapplication.js中),然后在模板中使用它:

对于控制器特定的 JavaScript:

<%= javascript_include_tag params[:controller] %>
Run Code Online (Sandbox Code Playgroud)

对于控制器特定的 CSS:

<%= stylesheet_link_tag params[:controller] %>
Run Code Online (Sandbox Code Playgroud)