如何在使用rails资产管道时内联css

而不是让页面包含带有链接的样式标记,从中可以使用rails的stylesheet_link_tag帮助方法将其添加到我的视图中,我希望将css内联直接放在页面内。

这是我到目前为止提出的:

 %style(type="text/css")=File.read(physical_asset_path("email.css")) 

但我找不到任何rails的帮助方法,它给了我一个资产的物理路径 – physical_asset_path只是我发明的虚拟方法。

有人知道如何在使用rails 3.2.x时获取资产的物理路径吗?

是否有更简单/更好的方式来获取样式表 – 来自共轨资产路径中的css文件 – 内联?

使用案例:大多数电子邮件客户端在没有用户确认的情况下不访问外部源(如css,images)。 因此,为了正确显示电子邮件,我需要将CSS嵌入到电子邮件的HTML中。

使用premailer或premailer-rails3

https://github.com/fphilipe/premailer-rails3或https://github.com/alexdunae/premailer

乔的书呆子党说:

我们还使用Premailer gem自动内联电子邮件视图中的链接样式表。 我们的电子邮件布局类似于:

 %html %head = stylesheet_link_tag 'email' %style{:type => "text/css"} :sass @media all and (max-width: 480px) table#container width: auto !important max-width: 600px !important ... and so on for the mobile code %body Email body here. %table Lots of tables. 

我们在HTML中包含样式表。 预编译器下载,处理它,并在HTML中内嵌插入css规则。

@media规则需要在电子邮件布局中内联,因为Premailer无法处理那些在单独的css文件中的内容。

我们使用premailer-rails3将Premailer集成到Rails 3.不幸的是,我们在premailer和premailer-rails3中发现了一堆bug。 我们的项目分支在https://github.com/joevandyk/premailer和https://github.com/joevandyk/premailer-rails3 。 这些forks修复了一些编码错误,删除了premailer-rails3完成的一些奇怪的css处理,允许预编译器不删除电子邮件布局中的嵌入式规则,以及其他一些东西。

我们还在sass-rails中发现了一个错误,你无法在内联sass代码中嵌入image-urls。 当电子邮件实际发送时,请参阅https://github.com/rails/sass-rails/issues/71 Premailer-rails3挂钩到ActionMailer,而不仅仅是生成。 运行测试时,实际上并未发送电子邮件,因此premailer-rails3挂钩在测试期间不会运行。 我没有花时间看看是否有可能在测试期间让预编译器处理运行,但这将是一件好事。

此外,我们在premailer-rails3上的分支假设您希望预编程器出去并实际下载链接的CSS文件。 应该可以使用Rails 3.1资产管道来获取已处理的css而无需下载它。 非常特别的感谢Jordan Isip做了一个非常烦人的工作,确保电子邮件在所有不同的客户端看起来很棒。 写CSS / HTML看起来并不好玩。

更新:

Roadie似乎是一个更好的选择。 感谢Seth Bro指出它。

Rails.application.assets.find_asset('email').to_s将编译后的资产作为字符串返回。

(对不起,这个答案是html ,而不是HAML ……但这对HAML粉丝来说应该不是问题)

我在寻找一种内联Sass的方法时发现了这个问题,将编译为css Sass编译成html来创建HTML电子邮件模板。

结合上面的建议,我在我的html页面的head使用了以下代码:

  

此代码将Sass编译为CSS ,然后将css插入

标记。 html_safe确保不会转义css中使用的任何引号( '" )或尖括号( >< )。

path/to/sass/file与创建样式表链接标记时使用的path/to/sass/file相同:

 <%= stylesheet_link_tag 'path/to/sass/file', :media => 'all' %> 

Rails.application.assets['asset.js']仅适用于本地环境,因为在生产和登台环境中禁用了rails资产编译。

当使用rails资产管道时,应使用Rails.application.assets_manifest.find_sources('asset.js').first.to_s.html_safe来内联css。

无法在Seth Bro的回答中添加评论。 最好使用#[]而不是#find_assetRails.application.assets["email"].to_s

重新“资产不会被压缩”。 这不是真的。 如果您启用了压缩器(在rails配置中),它将被压缩:

 Rails.application.configure do # ... config.assets.css_compressor = :sass config.assets.js_compressor = :uglify end 

请注意,默认情况下,这在生产环境中启用( config/environments/production.rb )。

我试图内联css用于带有rails的google amp兼容页面。 我从vyachkonovalov找到了以下帮手,这是我在生产和本地工作的唯一方法。

将以下内容添加到erb模板:

  

还有ApplicationHelper的帮手。 它在本地和生产中都很完美。

 module ApplicationHelper def asset_to_string(name) app = Rails.application if Rails.configuration.assets.compile app.assets.find_asset(name).to_s else controller.view_context.render(file: File.join('public/assets', app.assets_manifest.assets[name])) end end 

tl; dr(没有Roadie):

 %style(type="text/css") = render template: '../assets/stylesheets/email_responsive.css' 

为了实际应用CSS作为内联样式,我推荐roadie-rails (这是Roadie的Rails包装器)。 它还有其他简洁的function,如absolutizing href s, src s等。

结合内联( email.scss )和非内联( email_responsive.css )样式表的email_responsive.css ,两者都驻留在app/assets/stylesheets

 -# This will be inlined and applied to HTML elements. -# Note that you need to include this in your asset config, eg: -# Rails.application.config.assets.precompile += %w(... email.css) -# (You need to list it as `email.css` even if it's actually `email.scss`.) = stylesheet_link_tag 'email' -# Eg for media queries which can't be inlined - yeah, some iOS devices support them. -# This will not be inlined and will be included as is (thanks to `data-roadie-ignore`). -# `template:` marks it as a full template rather than a partial and disables `_` prefix. -# We need to add the extension (`.css`) since it's non-standard for a view. %style(type="text/css" data-roadie-ignore) = render template: '../assets/stylesheets/email_responsive.css' 

你可以用这个:

 Rails.root.join('public', ActionController::Base.helpers.asset_path("email.css")[1..-1]).read.html_safe 

有同样的问题,使用@ phlegx对 Premailer中类似问题的回答解决了这个问题。

对于您需要使用的环境安全解决方案

 (Rails.application.assets || ::Sprockets::Railtie.build_environment(Rails.application)).find_asset('email.css').to_s 

我在我的应用程序中将其打包成帮助器:

 # app/helpers/application_helper.rb # Returns the contents of the compiled asset (CSS, JS, etc) or an empty string def asset_body(name) (Rails.application.assets || ::Sprockets::Railtie.build_environment(Rails.application)).find_asset(name).to_s end