Menggunakan pipa Rails 3.1 asset untuk secara kondisional menggunakan css tertentu

166

Saya sedang dalam proses membangun aplikasi solo Rails pertama saya menggunakan Rails 3.1.rc5. Masalah saya adalah saya ingin situs saya me-render berbagai file CSS secara kondisional. Saya menggunakan Blueprint CSS dan saya mencoba membuat sprocket / rel membuat screen.csssebagian besar waktu, print.csshanya saat mencetak, dan ie.csshanya ketika situs diakses dari Internet Explorer.

Sayangnya, *= require_treeperintah default di application.cssmanifes mencakup semua yang ada di assets/stylesheetsdirektori dan menghasilkan campur aduk CSS yang tidak menyenangkan. Solusi saya saat ini adalah semacam metode brute-force di mana saya menentukan semuanya secara individual:

Dalam application.css:

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

Di sebagian stylesheet saya (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"

Ini bekerja tetapi tidak terlalu cantik. Saya telah melakukan beberapa jam pencarian bahkan untuk sejauh ini tetapi saya berharap ada beberapa cara yang lebih mudah untuk melakukannya yang baru saja saya lewatkan. Jika saya bahkan dapat secara selektif membuat direktori tertentu (tanpa termasuk subdirektori) itu akan membuat keseluruhan proses menjadi jauh lebih tidak kaku.

Terima kasih!

talon55
sumber

Jawaban:

223

Saya telah menemukan cara untuk membuatnya menjadi kurang kaku dan bukti di masa depan dengan masih menggunakan pipa aset tetapi memiliki stylesheet dikelompokkan. Ini tidak jauh lebih sederhana daripada solusi Anda, tetapi solusi ini memungkinkan Anda untuk secara otomatis menambahkan stylesheet baru tanpa harus mengedit ulang seluruh struktur lagi.

Yang ingin Anda lakukan adalah menggunakan file manifes terpisah untuk memecah hal-hal. Pertama, Anda harus mengatur ulang app/assets/stylesheetsfolder Anda :

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

Kemudian Anda mengedit tiga file manifes:

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

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

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

Selanjutnya Anda memperbarui file tata letak aplikasi Anda:

<%= 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]-->

Terakhir, jangan lupa untuk menyertakan file manifes baru ini di config / environment / production.rb Anda:

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

Memperbarui:

Seperti yang ditunjukkan Max, jika Anda mengikuti struktur ini, Anda harus memperhatikan referensi gambar. Anda punya beberapa pilihan:

  1. Pindahkan gambar untuk mengikuti pola yang sama
    • Perhatikan bahwa ini hanya berfungsi jika gambar tidak semuanya dibagikan
    • Saya berharap ini akan menjadi non-starter untuk sebagian besar karena hal itu terlalu rumit
  2. Kualifikasi jalur gambar:
    • background: url('/assets/image.png');
  3. Gunakan pembantu SASS:
    • background: image-url('image.png');
gcastro
sumber
1
Meskipun ini adalah organisasi yang bagus untuk file-file tersebut, saya percaya ini masih memecahkan masalah penting dengan cara yang sama seperti pertanyaan itu sendiri.
semperos
@emperos, Anda benar bahwa bentuk solusi pada dasarnya sama tetapi proposal saya masih memungkinkan kami untuk menggunakan pipa aset untuk keseluruhan stylesheet. Saya tidak yakin apakah ada cara lain untuk secara selektif memasukkan bagian dari gaya kecuali itu pada stylesheet terpisah. Setidaknya dengan cara ini kami mengkompilasi ke hanya beberapa file CSS.
gcastro
5
Sesuatu seperti ini di panduan Rails Asset Pipeline akan bagus sebenarnya. terima kasih
Bashar Abdullah
3
Ada gotcha: jika Anda mengikuti struktur ini dan menggunakan .cssfile sederhana maka semua gambar Anda akan rusak. Misalnya background: url('image.png')akan diterjemahkan ke jalan /assets/all/image.png(pikiran semua yang ada di jalan). Sebaliknya ini bekerja: background: url('/assets/image.png). Jika ada solusi yang lebih mudah untuk ini, silakan posting. Selain menggunakan SASS yang memiliki metode pembantu yang mungkin menyelesaikan jalur dengan benar.
Maks
1
@ ExiRe, ya. Semua stylesheet atau file JS / manifes yang tidak mengikuti pola standar perlu ditambahkan ke array precompile (lihat: guides.rubyonrails.org/asset_pipeline.html#precompiling-assets )
gcastro
10

Datangi masalah ini hari ini.

Akhirnya menempatkan semua stylesheet khusus IE ke lib / aset / stylesheet dan membuat satu file manifes per versi IE. Kemudian di application.rb tambahkan mereka ke daftar hal-hal yang harus dikompilasi:

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

Dan dalam tata letak Anda, sertakan file manifes secara kondisional dan Anda siap melakukannya!

Anthony Alberto
sumber
2

Itu cara yang cukup rapi untuk melakukannya. Saya menggunakan kelas bersyarat pada html atau modernizr. Lihat artikel ini untuk representasi yang baik tentang apa yang melakukan apa. modernizr-vs-conditional-classes-on-html

mrmonroe
sumber