26

我不想让页面包含一个样式标签,其中包含一个从中获取 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、图像)。因此,要正确显示电子邮件,我需要将 CSS 嵌入电子邮件的 HTML 中。

4

9 回答 9

64

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

于 2012-08-01T20:37:37.927 回答
16

使用 premailer 或 premailer-rails3

https://github.com/fphilipe/premailer-rails3https://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 中包含一个样式表。Premailer 下载、处理并在 HTML 中内联插入 css 规则。

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

我们使用 premailer-rails3 将 Premailer 集成到 Rails 3 中。不幸的是,我们在 premailer 和 premailer-rails3 中发现了一堆错误。我们的项目分支位于 https://github.com/joevandyk/premailerhttps://github.com/joevandyk/premailer-rails3。分叉修复了一些编码错误,删除了一些由 premailer-rails3 完成的奇怪的 css 处理内容,允许 premailer 不去除电子邮件布局中的嵌入规则,以及其他一些事情。

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

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

更新:

Roadie似乎是一个更好的选择。感谢赛斯兄弟指出。

于 2012-04-30T16:18:15.727 回答
12

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

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

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

<style type="text/css">
  <%= Rails.application.assets['path/to/sass/file'].to_s.html_safe %>
</style>

此代码编译SassCSS,然后将 css 插入到<style>标签中。html_safe确保 css 中使用的任何引号 ( and ')"或尖括号 ( >and <) 不会被转义。

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

<%= stylesheet_link_tag 'path/to/sass/file', :media => 'all' %>
于 2016-02-08T21:51:34.470 回答
7

Rails.application.assets['asset.js']将仅在本地环境中工作,因为在生产环境和暂存环境中都禁用了 rails 资产编译。

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

于 2016-09-28T07:06:38.260 回答
4

无法对 Seth Bro 的回答添加评论。你最好使用#[]而不是#find_asset: Rails.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)。

于 2013-07-24T22:02:12.197 回答
4

有同样的问题,使用@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
于 2018-08-28T14:24:41.650 回答
3

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

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

<style amp-custom>
  <%= asset_to_string('application.css').html_safe %>
</style>

和帮手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
于 2016-11-16T10:06:56.530 回答
1

tl;博士(没有 Roadie):

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

对于实际将 CSS 应用为内联样式,我推荐roadie-rails(它是Roadie的 Rails 包装器)。它还具有其他简洁的功能,例如绝对化hrefs、srcs 等。

结合了内联 ( email.scss) 和非内联 ( 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, e.g.:
-# 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'


-# E.g. 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'
于 2015-12-24T22:38:30.580 回答
0

你可以使用这个:

Rails.root.join('public', ActionController::Base.helpers.asset_path("email.css")[1..-1]).read.html_safe
于 2018-08-17T13:39:58.693 回答