Versi @ impor dari theme.css tema induk

28

Konteks

Saya membangun tema anak berdasarkan Twenty Thirteen yang bekerja dengan cukup baik. Setelah memperbarui tema induk ke versi 1.3, saya melihat perilaku aneh dengan gaya yang disebabkan oleh tema induk dalam cache style.css.

Berikut adalah isi dari tema anak saya style.css(menghilangkan header)

/* =Imports styles from the parent theme
-------------------------------------------------------------- */
@import url('../twentythirteen/style.css');

Jadi tema anak style.csstidak lebih dari mengimpor tema orang tua style.css.

Saya juga memiliki file css lain dengan kustomisasi tema anak saya yang saya enqueue seperti di functions.php:

// Enqueue parent theme's style.css (faster than using @import in our style.css)
$themeVersion = wp_get_theme()->get('Version');

// Enqueue child theme customizations
wp_enqueue_style('child_main', get_stylesheet_directory_uri() . '/css/main.css',
    null, $themeVersion);

Ini memberi saya url css yang sangat bagus seperti ini: domain.com/wp-content/themes/toutprettoutbon/css/main.css?ver=1.0.1yang memastikan style sheet dimuat ulang ketika tema anak diperbarui.

Sekarang masalahnya

Pernyataan @import url('../twentythirteen/style.css');ini sepenuhnya independen dari versi tema induk yang mendasari. Bahkan, tema induk dapat diperbarui tanpa memperbarui tema anak tetapi browser masih akan menggunakan versi cache yang lama ../twentythirteen/style.css.

Kode yang relevan di Twenty Thirteen yang memberikan style.css:

function twentythirteen_scripts_styles() {
    // ...

    // Add Genericons font, used in the main stylesheet.
    wp_enqueue_style( 'genericons', get_template_directory_uri() . '/genericons/genericons.css', array(), '3.03' );

    // Loads our main stylesheet.
    wp_enqueue_style( 'twentythirteen-style', get_stylesheet_uri(), array(), '2013-07-18' );
    // Note usage of get_stylesheet_uri() which actually enqueues child-theme/style.css

    // Loads the Internet Explorer specific stylesheet.
    wp_enqueue_style( 'twentythirteen-ie', get_template_directory_uri() . '/css/ie.css', array( 'twentythirteen-style' ), '2013-07-18' );
}
add_action( 'wp_enqueue_scripts', 'twentythirteen_scripts_styles' );

Saya dapat memikirkan beberapa cara untuk mengatasi masalah ini tetapi tidak ada yang benar-benar memuaskan:

  1. Perbarui tema anak saya setiap kali tema induk diperbarui untuk mengubah string versi di style.css(misalnya @import url('../twentythirteen/style.css?ver=NEW_VERSION');). Ini menciptakan tautan yang tidak perlu dan mengganggu antara versi tema induk dan anak.

  2. Pada anak saya functions.php, 1) wp_dequeue_styletema termasuk anak style.cssdan 2) wp_enqueue_styleyang orangtua tema ini style.csslangsung DENGAN string versi. Ini mengacaukan urutan css yang antri dalam tema induk.

  3. Gunakan style_loader_tagfilter untuk memodifikasi <link>tag css yang dihasilkan untuk style.cssdan memodifikasi jalur untuk menunjuk langsung ke tema indukstyle.css DENGAN string versi. Tampaknya agak tidak jelas untuk kebutuhan yang sama (penghilang cache).

  4. Buang tema orang tua di tema style.cssanak saya style.css. Sama seperti (1) sungguh, tetapi sedikit lebih cepat.

  5. Jadikan tema anak saya style.cssmenjadi symlink ke tema orang tua style.css. Ini sepertinya cukup retas ...

Apakah saya melewatkan sesuatu? Ada saran?

sunting

Menambahkan genericicons.cssdan ie.cssstyle sheet dalam tema induk untuk menjelaskan mengapa saya tidak dapat mengubah @importpernyataan css wp_enqueue_styledi dalam tema anak saya. Saat ini, dengan @importpernyataan di tema anak saya style.css, saya memiliki urutan ini di halaman yang dihasilkan:

  1. twentythirteen / genericons / genericons.css -> enqueued oleh theme induk
  2. child-theme / style.css -> enqueued oleh theme parent, @import twentythirteen / style.css
  3. dua puluh tiga belas / css / ie.css -> enqueued oleh tema induk
  4. child-theme / css / main.css -> enqueued oleh child theme

Jika saya menyatakan bahwa orang tua style.csssebagai ketergantungan main.css, ini akan menjadi:

  1. twentythirteen / genericons / genericons.css -> enqueued oleh theme induk
  2. child-theme / style.css -> kosong, enqueued oleh theme induk
  3. dua puluh tiga belas / css / ie.css -> enqueued oleh tema induk
  4. dua puluh tiga belas / style.css -> enqueued oleh tema anak sebagai ketergantungan dari main.css
  5. child-theme / css / main.css -> enqueued oleh child theme

Perhatikan bahwa ie.css sekarang disertakan sebelum tema induk style.css. Saya tidak ingin mengubah urutan enqueuing file css tema orang tua karena saya tidak dapat menganggap bahwa ini tidak akan menyebabkan masalah dengan prioritas aturan css.

bernie
sumber
5
Jangan pernah gunakan @import, tetapkan stylesheet tema orangtua sebagai ketergantungan dari stylesheet Anda sendiri .
fuxia
Saya tahu ini bukan pendekatan terbaik tetapi direkomendasikan di sini: codex.wordpress.org/Child_Themes
bernie
Juga, melakukan apa yang Anda sarankan tidak memperbaiki masalah saya. Tema induk style.csstidak akan disertakan di tempat yang sama seperti sekarang. Induk menyertakan file css lain yang harus ada di antara style.csscss temanya dan anak saya.
bernie
3
Abaikan codex sepenuhnya. Penuh dengan informasi yang salah. Menggunakan parameter dependensi akan memasukkan stylesheet dalam urutan yang benar.
fuxia
Silakan lihat edit saya.
bernie

Jawaban:

19

Anda tidak harus menggunakan @import. Sebaiknya tidak. Menggunakan pendekatan enqueued mungkin lebih baik di sekitar.

Inilah bagian yang relevan dari kode dua puluh tiga:

function twentythirteen_scripts_styles() {
...
    // Loads our main stylesheet.
    wp_enqueue_style( 'twentythirteen-style', get_stylesheet_uri(), array(), '2013-07-18' );
...
}
add_action( 'wp_enqueue_scripts', 'twentythirteen_scripts_styles' );

Inilah yang Anda lakukan dalam kode Anda:

function child_scripts_styles() {
    wp_enqueue_style( 'child-style', get_stylesheet_directory_uri().'/css/main.css', array('twentythirteen-style'), 'YOUR_THEME_VERSION' );
}
add_action( 'wp_enqueue_scripts', 'child_scripts_styles' );

Jika main.css Anda harus mengikuti style.css induk, maka Anda hanya membuatnya bergantung pada itu.

Sekarang, jika Anda juga memiliki B.css pada anak, maka Anda mengatur dependensi sesuai:

function child_scripts_styles() {
    wp_enqueue_style( 'child-B-style', get_stylesheet_directory_uri().'/B.css', array('twentythirteen-style'), 'YOUR_THEME_VERSION' );
    wp_enqueue_style( 'child-style', get_stylesheet_directory_uri().'/css/main.css', array('child-B-style'), 'YOUR_THEME_VERSION' );
}
add_action( 'wp_enqueue_scripts', 'child_scripts_styles' );

Buat dependensi yang Anda tetapkan untuk setiap item sebenarnya mencerminkan apa sebenarnya dependensi itu. Jika main.css harus datang setelah B.css, maka itu tergantung padanya. Jika B.css harus berasal dari style.css induk, maka B tergantung pada itu. Sistem enqueue akan mengatasinya untuk Anda.

Dan jika Anda tidak benar-benar menggunakan style anak .css untuk apa pun, maka Anda tidak perlu mengubahnya sama sekali . Ini bisa menjadi pengganti untuk menyimpan informasi tajuk tema Anda. Tidak menggunakannya? Jangan memuatnya.

Juga, apa sebenarnya yang Anda lakukan sehingga sangat bergantung pada pemesanan di sini? CSS tidak peduli tentang urutan pemuatan di sebagian besar situasi. CSS lebih tergantung pada spesifisitas pemilih. Jika Anda ingin menimpa sesuatu, Anda membuat pemilih Anda untuk itu lebih spesifik. Itu bisa didahulukan, atau terakhir, atau apa pun di antaranya, pemilih yang lebih spesifik selalu menang.

Edit

Membaca komentar Anda dan melihat kodenya lebih dekat, saya melihat di mana kesalahannya. Kode dua puluh tiga belas adalah enqueueing "get_stylesheet_uri ()", yang dalam kasus tema anak, akan menjadi file style.css tema anak Anda, bukan file orangtua. Itulah sebabnya @import berfungsi, dan tetap memesan yang sama (yang lagi-lagi, tidak masalah sebanyak yang Anda pikirkan).

Dalam hal itu, jika Anda tidak ingin menggunakan impor, saya akan merekomendasikan enqueue style.css induk secara langsung. Seperti itu:

function child_scripts_styles() {
    wp_enqueue_style( 'parent-style', get_template_directory_uri().'/style.css', array() );
}
add_action( 'wp_enqueue_scripts', 'child_scripts_styles' );

Kode di function.php tema anak berjalan terlebih dahulu, jadi wp_enqueue_scripts Anda sendiri akan berjalan terlebih dahulu, dan ini akan memunculkan style.css tema orangtua, yang tidak dilakukan sendiri oleh tema induknya (karena itu sebenarnya enqueueing style.css anak Anda). Dengan tidak membuatnya bergantung pada apa pun, sama seperti induknya, maka itu hanya akan dimasukkan ke dalam output dengan benar. Perhatikan bahwa urutan file ini dan genericons.css tidak masalah, karena asli "gaya dua puluh tiga belas" tidak memiliki genericons.css sebagai ketergantungan terdaftar.

Style.css anak Anda sendiri akan dimuat, dan jujur, di sinilah Anda harus meletakkan perubahan Anda untuk tema anak, bukan ke main.css terpisah. Tidak ada yang mencegah Anda menempatkan perubahan di sana, tetapi tidak ada alasan nyata untuk memiliki file css tambahan.

Otto
sumber
Saya sepenuhnya setuju bahwa @importini bukan cara terbaik untuk pergi. Silakan lihat bagian "edit" saya untuk informasi yang lebih tepat. Saya tidak memiliki kebutuhan khusus mengenai pemesanan css. Saya hanya tidak ingin memodifikasi urutan internal file css tema induk yang dapat menyebabkan masalah dengan prioritas aturan css.
bernie
Untuk memperjelas, B.css (sekarang diubah menjadi ie.css yang dimaksud) bukan bagian dari tema anak saya, tetapi sebenarnya bagian dari tema induk.
bernie
2
Jika Anda ingin gaya Anda muncul setelah gaya ie.css, maka buat gaya Anda sendiri bergantung padanya. Namanya adalah "dua puluh tiga belas-yaitu". Urutan sepenuhnya dikelola oleh dependensi apa yang Anda nyatakan, tetapi sekali lagi, dengan CSS, urutan sebenarnya dari mereka dalam dokumen biasanya tidak masalah, jadi saya tidak yakin mengapa Anda terlalu peduli tentang hal itu.
Otto
2
Mengedit jawaban saya untuk memasukkan pendekatan yang berbeda.
Otto
Ya saya kira saya terbawa dengan "kebutuhan" untuk tetap memesan css. Jika urutan itu benar-benar penting untuk tema induk, itu harus dinyatakan dalam dependensi.
bernie
9

Jawaban saya sebelumnya terlalu rumit dan berpotensi tidak menghargai rantai ketergantungan tema orang tua (lihat catatan di jawaban lain).

Berikut ini cara lain yang lebih sederhana yang seharusnya bekerja lebih baik:

function use_parent_theme_stylesheet() {
    // Use the parent theme's stylesheet
    return get_template_directory_uri() . '/style.css';
}

function my_theme_styles() {
    $themeVersion = wp_get_theme()->get('Version');

    // Enqueue our style.css with our own version
    wp_enqueue_style('child-theme-style', get_stylesheet_directory_uri() . '/style.css',
        array(), $themeVersion);
}

// Filter get_stylesheet_uri() to return the parent theme's stylesheet 
add_filter('stylesheet_uri', 'use_parent_theme_stylesheet');

// Enqueue this theme's scripts and styles (after parent theme)
add_action('wp_enqueue_scripts', 'my_theme_styles', 20);

Idenya adalah dengan hanya memfilter panggilan ke get_stylesheet_uri()dalam tema induk untuk mengembalikan stylesheet itu sendiri alih-alih tema anak. Stylesheet tema anak kemudian enqueued kemudian di hook tindakan my_theme_styles.

bernie
sumber
Sebagai catatan: 1) Kode Anda akan menghasilkan html yang sama persis seperti menggunakan @importversi lama , tidak ada dampak pada kinerja sama sekali, akan ada dua permintaan style.css terpisah ke server 2) Jawaban ini menjatuhkan seluruh ketergantungan semuanya bersama-sama ... 3) Anda dapat memeriksa apa get_template_directory_uridan get_template_stylesheet_urilakukan di sini: core.trac.wordpress.org/browser/tags/4.8/src/wp-includes/... Sekali lagi, tidak perlu untuk sebagian besar kode itu.
bg17aw
1
@ bg17aw menggunakan wp_enqueue_stylesecara otomatis menambahkan string kueri penghilang cache ke url yang dihasilkannya (misalnya ?ver=2013-07-18) berdasarkan versi tema. Ini tidak dilakukan dengan @importpernyataan.
bernie
2

peringatan

Solusi ini tidak menghargai ketergantungan tema orang tua ! Mengubah nama pegangan tema induk memengaruhi rantai ketergantungan yang ditetapkan dalam tema induk. Lihat jawaban saya yang jauh lebih sederhana .

jawaban orignal

Meskipun jawaban Otto cukup bagus, saya berakhir dengan ini di functions.php tema anak saya

function my_theme_styles() {
    global $wp_styles;
    $parentOriginalHandle = 'twentythirteen-style';
    $parentNewHandle = 'parent-style';

    // Deregister our style.css which was enqueued by the parent theme; we want
    // to control the versioning ourself.
    $parentStyleVersion = $wp_styles->registered[$parentOriginalHandle]->ver;
    $parentDeps = $wp_styles->registered[$parentOriginalHandle]->deps;
    wp_deregister_style($parentOriginalHandle);

    // Enqueue the parent theme's style.css with whatever version it used instead
    // of @import-ing it in the child theme's style.css
    wp_register_style($parentNewHandle, get_template_directory_uri() . '/style.css',
        $parentDeps, $parentStyleVersion);

    // Enqueue our style.css with our own version
    $themeVersion = wp_get_theme()->get('Version');
    wp_enqueue_style($parentOriginalHandle, get_stylesheet_directory_uri() . '/style.css',
        [$parentNewHandle], $themeVersion);
}

// Run this action action the parent theme has enqueued its styles.
add_action('wp_enqueue_scripts', 'my_theme_styles', 20);

Ini mempertahankan style.cssurutan dan nomor versi tema orang tua sambil mengontrol versi tema anak style.css.

bernie
sumber
5
Ini mengejutkan saya bahwa perangkat lunak blog paling populer membutuhkan 20 baris kode hanya untuk mengubah CSS dari tema yang ada. Saya kira itu keamanan pekerjaan.
Carl G
Saya harus pindah [$parentNewHandle]kearray($parentNewHandle)
Carl G
@ CarlG: sintaks array yang saya gunakan (kurung) diperkenalkan di PHP 5.4.
bernie
Untuk upvoters: silakan lihat jawaban saya yang lain yang memecahkan masalah dengan yang ini.
bernie
Itu semua adalah kesalahpahaman besar, tidak perlu untuk semua itu. Faktanya, @importmetode lama juga berfungsi, harap bandingkan kedua metode ini. Adapun ketergantungan tema anak pada tema orang tua, tidak perlu untuk itu juga. Anak style.cssselalu dimuat setelah orangtua, setidaknya dari tes saya. Cinta terbukti salah.
bg17aw