Rails中html_safe方法规避HTML实体问题:AMP页面内联样式输出异常
Let's tackle this AMP inline style issue you're facing. The root problem here is that your CSS content (especially the @font-face rules) is getting HTML-entity escaped when rendered, which breaks AMP style validation and font loading. Let's break down the fixes:
Why Your Current Code Isn't Working
When using = in HAML, it automatically escapes HTML entities by default. Even adding .html_safe might not work as expected if the string returned by Rails.application.assets['amp/application'].to_s hasn't been properly marked as safe, or if HAML's escaping takes precedence over the html_safe flag.
Solution 1: Use HAML's Unescaped Output (!=)
Replace the = with != in your HAML code. This tells HAML to render the content without any HTML escaping entirely, which is exactly what we need for raw CSS:
- if Rails.application.assets && Rails.application.assets['amp/application'] %style(amp-custom) != Rails.application.assets['amp/application'].to_s - else %style(amp-custom) != File.read("#{Rails.root}/public#{stylesheet_path('amp/application', host: nil)}")
Solution 2: Use Rails' raw Helper
If you prefer sticking with = in HAML, wrap your content with Rails' raw helper. This method explicitly marks the string as safe to render without escaping, overriding HAML's default behavior:
- if Rails.application.assets && Rails.application.assets['amp/application'] %style(amp-custom) = raw(Rails.application.assets['amp/application'].to_s) - else %style(amp-custom) = raw(File.read("#{Rails.root}/public#{stylesheet_path('amp/application', host: nil)}"))
Additional Checks to Ensure Success
- Verify Precompiled Assets (Production): Make sure your
amp/application.cssis being properly precompiled in production. Check thepublic/assetsdirectory after deployment to confirm the CSS file exists and contains the correct@font-facerules without pre-escaped entities. - Development Environment Testing: In development, Sprockets compiles assets on the fly. Double-check that
Rails.application.assets['amp/application'].to_sreturns raw, unescaped CSS by inspecting it in the Rails console:
If you see HTML entities here, you might need to adjust your Sprockets configuration to avoid escaping during compilation.puts Rails.application.assets['amp/application'].to_s
Either of these solutions should resolve the HTML entity issue and get your AMP styles rendering correctly.
内容的提问来源于stack exchange,提问作者Roberto Pezzali

