Railsのstylesheet_link_tag
ヘルパーメソッドを使用してビューに追加できるcssの取得元のリンクを含むスタイルタグをページに含める代わりに、cssをページ内に直接インライン化する必要があります。
これは私がこれまでに思いついたものです:
%style(type="text/css")=File.read(physical_asset_path("email.css"))
しかし、アセットの物理パスを提供するRailsのヘルパーメソッドが見つかりません。physical_asset_path
は私が発明したダミーのメソッドです。
Rails 3.2.xを使用するときに、アセットの物理パスを取得する方法を知っている人はいますか?
コモンRailsアセットパス内のcssファイルから-インラインでスタイルシートを取得するためのより簡単でより良い方法はありますか?
使用例:ほとんどの電子メールクライアントは、ユーザーの確認なしに外部ソース(css、画像など)にアクセスしません。したがって、電子メールを適切に表示するには、電子メールのHTML内にCSSを埋め込む必要があります。
Premailerまたはpremailer-Rails3を使用
https://github.com/fphilipe/premailer-Rails または 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にスタイルシートを含めます。 Premailerはそれをダウンロードして処理し、cssルールをHTMLにインラインで挿入します。
Premailerはまだ別のcssファイルにあるルールを処理できないため、@ mediaルールはメールレイアウトでインラインにする必要があります。
Premailer-Rails3を使用してPremailerをRails 3.残念ながら、premailerとpremailer-Rails3に多数のバグが見つかりました。プロジェクトのフォークは https:/ /github.com/joevandyk/premailer および https://github.com/joevandyk/premailer-Rails 。フォークはいくつかのエンコーディングのバグを修正し、premailerによって行われたいくつかの奇妙なcss処理を削除します- Rails3では、プリメーラーがメールレイアウトに埋め込まれたルールを取り除かないようにできます。
また、sass-Railsにバグがあり、インラインsassコードにimage-urlを埋め込むことができません。 https://github.com/Rails/sass-Rails/issues/71 Premailer-Rails3は、電子メールが生成されるだけでなく、実際に配信されるときにActionMailerにフックします。を参照してください。テストを実行する場合、メールは実際には送信されないため、テスト中にpremailer-Rails3フックは実行されません。テスト中にプリメーラー処理を実行できるかどうかを確認するために時間を費やしたことはありませんが、それは良いことです。
また、premailer-Rails3でのフォークは、プリメーラーが出て実際にリンクされたCSSファイルをダウンロードすることを想定しています。 Rails 3.1アセットパイプラインを使用して、処理されたcssをダウンロードせずに取得できるはずです。メールの見栄えを良くするという非常に厄介な仕事をしてくれたJordanIsipに特に感謝します。 CSS/HTMLを書くのは面白くありませんでした。
更新:
Roadie の方が良いオプションのようです。指摘してくれたSeth Broに感謝します。
Rails.application.assets.find_asset('email').to_s
は、コンパイルされたアセットを文字列として返します。
(申し訳ありませんが、この回答はhtml
ではなくHAML
にありますが、HAML
ファンにとっては問題にはなりません)
この質問は、HTMLメールテンプレートを作成するためにSass
としてコンパイルされたcss
をhtml
にインライン化する方法を探しているときに見つけました。
上記のアドバイスを組み合わせて、head
ページのhtml
で次のコードを使用しました。
<style type="text/css">
<%= Rails.application.assets['path/to/sass/file'].to_s.html_safe %>
</style>
このコードはSass
をCSS
としてコンパイルし、CSSを<style>
タグに挿入します。 html_safe
は、cssで使用されている引用符('
および"
)または山括弧(>
および<
)がエスケープされないようにします。
path/to/sass/file
は、スタイルシートリンクタグを作成するときに使用するものと同じです。
<%= stylesheet_link_tag 'path/to/sass/file', :media => 'all' %>
_Rails.application.assets['asset.js']
_は、ローカル環境でのみ機能します。Railsアセットのコンパイルは、本番環境とステージング環境の両方で無効になっているためです。
Railsアセットパイプラインを使用する場合は、cssをインライン化するためにRails.application.assets_manifest.find_sources('asset.js').first.to_s.html_safe
を使用する必要があります。
SethBroの回答にコメントを追加できません。 #[]
の代わりに #find_asset
:Rails.application.assets["email"].to_s
。
再「資産は圧縮されません」。それは真実ではない。コンプレッサーを有効にしている場合は圧縮されます(Rails config):
Rails.application.configure do
# ...
config.assets.css_compressor = :sass
config.assets.js_compressor = :uglify
end
デフォルトでは、これは実稼働環境で有効になっていることに注意してください(config/environments/production.rb
)。
Railsのグーグルアンプ互換ページで使用するためにcssをインライン化しようとしていました。 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
同じ問題がありましたが、Premailerの同様の問題に対して @ phlegxの回答 を使用して解決しました。
環境に安全なソリューションを使用するには、
(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
tl; dr(Roadieなし):
%style(type="text/css")
= render template: '../assets/stylesheets/email_responsive.css'
実際にCSSをインラインスタイルとして適用する場合、 roadie-Rails をお勧めします(これは、Rails Roadie のラッパーです)。また、 href
s、src
sなどの絶対化などの他の優れた機能。
インライン(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'
あなたはこれを使うことができます:
Rails.root.join('public', ActionController::Base.helpers.asset_path("email.css")[1..-1]).read.html_safe