Verwenden der Rails 3.1-Assets-Pipeline zur bedingten Verwendung bestimmter CSS

166

Ich bin gerade dabei, meine erste Solo-Rails-App mit Rails 3.1.rc5 zu erstellen. Mein Problem ist, dass meine Site die verschiedenen CSS-Dateien unter bestimmten Bedingungen rendern soll. Ich verwende Blueprint CSS und versuche, Kettenräder / Schienen die screen.cssmeiste Zeit print.cssnur beim Drucken und ie.cssnur beim Zugriff auf die Site über Internet Explorer rendern zu lassen .

Leider enthält der Standardbefehl *= require_treeim application.cssManifest alles im assets/stylesheetsVerzeichnis und führt zu einem unangenehmen CSS-Durcheinander. Meine aktuelle Problemumgehung ist eine Art Brute-Force-Methode, bei der ich alles einzeln spezifiziere:

In application.css:

*= require_self
*= require home.css
...
*= require blueprint/screen.css

In meinen Stylesheets teilweise (haml):

<!--[if lt IE 9]
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
![endif]-->
= stylesheet_link_tag "application"
= stylesheet_link_tag 'blueprint/print', media: 'print'
<!--[if lt IE8]]
= stylesheet_link_tag 'blueprint/ie'
![endif]-->
= javascript_include_tag "application"

Das funktioniert, ist aber nicht besonders hübsch. Ich habe ein paar Stunden lang gesucht, um überhaupt so weit zu kommen, aber ich hoffe, dass es einen einfacheren Weg gibt, den ich gerade verpasst habe. Wenn ich sogar bestimmte Verzeichnisse selektiv rendern könnte (ohne Unterverzeichnisse einzuschließen), würde dies den gesamten Prozess viel weniger starr machen.

Vielen Dank!

talon55
quelle

Antworten:

223

Ich habe einen Weg gefunden, es weniger starr und zukunftssicher zu machen, indem ich weiterhin die Asset-Pipeline verwende, aber die Stylesheets gruppiert habe. Es ist nicht viel einfacher als Ihre Lösung, aber mit dieser Lösung können Sie automatisch neue Stylesheets hinzufügen, ohne die gesamte Struktur erneut bearbeiten zu müssen.

Was Sie tun möchten, ist, separate Manifestdateien zu verwenden, um die Dinge aufzubrechen. Zuerst müssen Sie Ihren app/assets/stylesheetsOrdner neu organisieren :

app/assets/stylesheets
+-- all
    +-- your_base_stylesheet.css
+-- print
    +-- blueprint
        +-- print.css
    +-- your_print_stylesheet.css
+-- ie
    +-- blueprint
        + ie.css
    +-- your_ie_hacks.css
+-- application-all.css
+-- application-print.css
+-- application-ie.css

Dann bearbeiten Sie die drei Manifestdateien:

/**
 * application-all.css
 *
 *= require_self
 *= require_tree ./all
 */

/**
 * application-print.css
 *
 *= require_self
 *= require_tree ./print
 */

/**
 * application-ie.css
 *
 *= require_self
 *= require_tree ./ie
 */

Als Nächstes aktualisieren Sie Ihre Anwendungslayoutdatei:

<%= stylesheet_link_tag "application-all", :media => "all" %>
<%= stylesheet_link_tag "application-print", :media => "print" %>

<!--[if lte IE 8]>
    <%= stylesheet_link_tag "application-ie", :media => "all" %>
<![endif]-->

Vergessen Sie nicht, diese neuen Manifestdateien in Ihre Konfiguration / Umgebungen / Produktion.rb aufzunehmen:

config.assets.precompile += %w( application-all.css application-print.css application-ie.css )

Aktualisieren:

Wie Max betonte, müssen Sie, wenn Sie dieser Struktur folgen, auf Bildreferenzen achten. Sie haben einige Möglichkeiten:

  1. Verschieben Sie die Bilder, um dem gleichen Muster zu folgen
    • Beachten Sie, dass dies nur funktioniert, wenn nicht alle Bilder gemeinsam genutzt werden
    • Ich gehe davon aus, dass dies für die meisten ein Nichtstarter sein wird, da es die Dinge zu sehr kompliziert
  2. Qualifizieren Sie den Bildpfad:
    • background: url('/assets/image.png');
  3. Verwenden Sie den SASS-Helfer:
    • background: image-url('image.png');
gcastro
quelle
1
Dies ist zwar eine nette Organisation der Dateien, aber ich glaube, sie löst das wesentliche Problem immer noch auf die gleiche Weise wie die Frage selbst.
Semperos
@semperos, Sie haben Recht, dass die Form der Lösung im Wesentlichen dieselbe ist, aber mein Vorschlag ermöglicht es uns weiterhin, die Asset-Pipeline für die Gesamtheit der Stylesheets zu verwenden. Ich bin mir nicht sicher, ob es eine andere Möglichkeit gibt, einen Teil der Stile selektiv einzuschließen, es sei denn, es befindet sich in einem separaten Stylesheet. Zumindest auf diese Weise kompilieren wir nur eine Handvoll CSS-Dateien.
Gcastro
5
So etwas im Rails Asset Pipeline-Handbuch wäre eigentlich gut. danke
Bashar Abdullah
3
Es gibt jedoch ein Problem: Wenn Sie dieser Struktur folgen und einfache .cssDateien verwenden, werden alle Ihre Bilder beschädigt. ZB background: url('image.png')wird auf den Pfad übersetzt /assets/all/image.png(beachte das All auf dem Pfad). Stattdessen funktioniert dies : background: url('/assets/image.png). Wenn es eine einfachere Lösung dafür gibt, posten Sie sie bitte. Anders als bei der Verwendung von SASS mit Hilfsmethoden, die den Pfad wahrscheinlich korrekt auflösen.
Max
1
@ExiRe, ja. Alle Stylesheets oder JS-Dateien / Manifeste, die nicht dem Standardmuster entsprechen, müssen dem vorkompilierten Array hinzugefügt werden (siehe: guide.rubyonrails.org/asset_pipeline.html#precompiling-assets )
gcastro
10

Kam heute über dieses Problem.

Am Ende wurden alle IE-spezifischen Stylesheets in lib / assets / stylesheets abgelegt und eine Manifestdatei pro IE-Version erstellt. Fügen Sie sie dann in application.rb zur Liste der Dinge hinzu, die vorkompiliert werden sollen:

config.assets.precompile += ["ie9.css", "ie7.css", "ie8.css", "ie.css"]

Wenn Sie diese Manifestdateien bedingt in Ihre Layouts aufnehmen, können Sie loslegen!

Anthony Alberto
quelle
2

Das ist eine ziemlich nette Art, es zu tun. Ich benutze bedingte Klassen auf HTML oder Modernizr. In diesem Artikel finden Sie eine gute Darstellung dessen, was was macht. modernizr-vs-bedingte-Klassen-auf-HTML

mrmonroe
quelle