web-dev-qa-db-fra.com

Comment intégrer des CSS lorsque vous utilisez le pipeline d'actifs Rails

Au lieu d’inclure dans la page une balise de style avec un lien permettant d’obtenir le fichier css, que je pourrais ajouter à mon affichage à l’aide de la méthode d’assistance stylesheet_link_tag de Rails, je souhaite que le fichier css soit directement inséré dans la page.

Voici ce que je suis arrivé jusqu'à présent:

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

Mais je ne trouve aucune méthode d'assistance de Rails qui me donne le chemin physique d'un actif - physical_asset_path est simplement une méthode factice inventée par moi.

Tout le monde sait comment obtenir le chemin physique d'un actif avec Rails 3.2.x? 

Existe-t-il un moyen plus simple/meilleur d’obtenir des feuilles de style - à partir de fichiers CSS dans les chemins d’accès aux ressources Rails courants - en ligne?

Cas d'utilisation: la plupart des clients de messagerie n'accèdent pas à des sources externes (telles que css, images) sans confirmation de l'utilisateur. Donc, pour que les emails soient correctement affichés, j'ai besoin d'intégrer le CSS dans le HTML des emails.

23
gucki

Utilisez premailer ou premailer-Rails3

https://github.com/fphilipe/premailer-Rails3 ou https://github.com/alexdunae/premailer

Joe Nerd Party dit:

Nous avons également utilisé la gemme Premailer pour insérer automatiquement la feuille de style Liée dans les vues de courrier électronique. Notre mise en page de courrier ressemble à quelque chose comme:

%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.

Nous incluons une feuille de style dans le HTML. Premailer le télécharge, le traite Et insère les règles CSS en ligne dans le code HTML.

Les règles @media doivent être intégrées à la mise en page du courrier électronique, car Premailer ne peut pas encore gérer celles qui se trouvent dans un fichier CSS séparé.

Nous utilisons premailer-Rails3 pour intégrer Premailer à Rails 3. Malheureusement, nous avons trouvé un tas de bugs dans Premailer et Premailer-Rails3. Nos projets sont à https://github.com/joevandyk/premailer et https://github.com/joevandyk/premailer-Rails3 . Les fourches corrigent quelques bogues de codage , Suppriment certains trucs bizarres de traitement des CSS effectués par Premailer-Rails3, permettent à premailer de ne pas supprimer les règles Incorporées dans les présentations de courrier électronique, et quelques autres. des choses. 

Nous avons également trouvé un bogue dans sass-Rails, dans lequel vous ne pouvez pas incorporer d’URL d’image dans le code sass en ligne . Voir https://github.com/Rails/sass-Rails/issues/71 Premailer-Rails3 s'accroche à ActionMailer lorsque le courrier électronique en cours de livraison est Et pas seulement généré. Lors de l'exécution de tests, le courrier électronique n'est pas réellement envoyé. Les hooks premailer-Rails3 ne sont donc pas exécutés pendant les tests . Je n’ai pas passé le temps de voir s’il était possible de faire fonctionner le traitement de Premailer pendant les tests, mais ce serait une bonne chose à faire.

De plus, nos fourchettes sur premailer-Rails3 supposent que vous voulez que premer soit Sorti et télécharge réellement les fichiers CSS liés. Il devrait être Possible d'utiliser le pipeline de ressources Rails 3.1 pour obtenir le css traité Sans le télécharger. Un remerciement tout particulier à Jordan Isip qui A fait le travail extrêmement ennuyeux de s’assurer que les courriels ont une belle apparence pour tous les Clients. Ecrire que CSS/HTML ne semblait pas amusant .

Mise à jour:

Roadie semble être une meilleure option. Merci à Seth Bro pour l'avoir signalé.

16

Rails.application.assets.find_asset('email').to_s retournera l'actif compilé sous forme de chaîne.

59
Seth Bro

(Désolé cette réponse est dans html, pas HAML… mais cela ne devrait pas poser de problème pour les fans de HAML)

J'ai trouvé cette question lorsque je cherchais un moyen d'insérer Sass en ligne compilé en tant que css dans html pour créer des modèles de courrier électronique HTML.

En combinant les conseils ci-dessus, j'ai utilisé le code suivant dans la head de ma page html:

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

Ce code compile Sass en tant que CSS et insère ensuite le css dans une balise <style>. Le html_safe garantit que les guillemets (' et ") ou les chevrons (> et <) utilisés dans le fichier css ne sont pas masqués. 

Le path/to/sass/file est identique à celui que vous utiliseriez lors de la création d'une balise de lien de feuille de style:

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

Rails.application.assets['asset.js'] fonctionnera uniquement dans l'environnement local, car la compilation d'actifs Rails est désactivée dans les environnements de production et de transfert.

Rails.application.assets_manifest.find_sources('asset.js').first.to_s.html_safe doit être utilisé pour les fichiers CSS incorporés lors de l'utilisation du pipeline d'actifs Rails.

5
ThisIzKp

Impossible d'ajouter un commentaire à la réponse de Seth Bro. Vous feriez mieux d'utiliser #[] au lieu de #find_asset: Rails.application.assets["email"].to_s.

Re "actif ne sera pas compressé". Ce n'est pas vrai. Il sera compressé si vous avez activé les compresseurs (dans la configuration Rails):

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

Notez que cette option est activée par défaut dans l'environnement de production (config/environments/production.rb).

4
ixti

J'essayais d'inline css pour une utilisation dans des pages compatibles avec Google ampères avec Rails. J'ai trouvé l'aide suivante de vyachkonovalov qui était la seule chose pour moi qui travaillais dans la production et localement.

Ajoutez les éléments suivants au modèle erb:

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

Et l’assistant à ApplicationHelper. Cela fonctionne parfaitement localement et dans la production.

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
2
steven iseki

tl; dr (sans Roadie):

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

Pour appliquer réellement les CSS en tant que styles en ligne, je recommande roadie-Rails (qui est un wrapper Rails pour Roadie ). Il a également d’autres fonctionnalités intéressantes comme absolutiser hrefs, srcs etc.

Utilisation combinant à la fois des feuilles de style insérées (email.scss) et non insérées (email_responsive.css), les deux résidant dans 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'
1
Halil Özgür

Avait le même problème, résolu en utilisant @ réponse de phlegx à un problème similaire dans Premailer.

Pour une solution respectueuse de l'environnement, vous devez utiliser

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

Je l'ai emballé dans une aide dans mon application:

# 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
0
Goulven

Vous pouvez utiliser ceci:

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