webdevqa.jp.net

親テーマのstyle.cssの@importのバージョン管理

コンテキスト

私は二十三十三に基づいて非常にうまく機能する子のテーマを構築しました。親テーマをバージョン1.3に更新した後、キャッシュされた親テーマのstyle.cssによって引き起こされたスタイリングの奇妙な振る舞いに気付きました。

これが私の子テーマのstyle.cssの内容です(ヘッダを省略)

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

そのため、子テーマのstyle.cssは、親テーマのstyle.cssをインポートすることに他なりません。

私はfunctions.phpにそのようにエンキューする私の子供のテーマのカスタマイズを含む別のcssファイルもあります。

// 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);

これは私にこのようなとても素晴らしいCSS URLを与えます:domain.com/wp-content/themes/toutprettoutbon/css/main.css?ver=1.0.1は子テーマが更新されたときにスタイルシートが再ロードされることを確認します。

今問題

ステートメント@import url('../twentythirteen/style.css');は、基礎となる親テーマのバージョンから完全に独立しています。実際、親テーマは子テーマを更新せずに更新できますが、ブラウザは古い../twentythirteen/style.cssのキャッシュされたバージョンを使用します。

style.cssをエンキューするTwenty Thirteenの関連コード:

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' );

私はこの問題を解決するためのいくつかの方法を考えることができますが、どれも本当に満足のいくものではありません。

  1. style.cssのバージョン文字列を変更するために親テーマが更新されるたびに私の子テーマを更新します(例:@import url('../twentythirteen/style.css?ver=NEW_VERSION');)。これは、親のテーマバージョンと子の間に不要で迷惑なリンクを作成します。

  2. 私の子供のfunctions.phpでは、1)wp_dequeue_styleは含まれている子テーマのstyle.cssおよび2)wp_enqueue_style parent テーマのstyle.cssは直接WITHバージョン文字列です。これは親テーマのキューに入れられたcssの順番を乱します。

  3. style_loader_tag フィルターを使用して、<link>用に生成されたcssのstyle.cssタグを変更し、 parent テーマのstyle.css WITHバージョン文字列を直接指すようにパスを変更します。そのような一般的な必要性(キャッシュ破壊)はややあいまいに思えます。

  4. 親テーマのstyle.cssを私の子テーマのstyle.cssにダンプします。 (1)と同じですが、少し速いです。

  5. 私の子テーマのstyle.cssを親テーマのstyle.cssへのシンボリックリンクにします。これはかなりハッキングですね….

私は何かを逃しましたか?助言がありますか?

編集する

私の子テーマでgenericicons.css cssステートメントをie.cssに変更できない理由を明確にするために、親テーマに@importおよびwp_enqueue_styleスタイルシートを追加しました。現在、私の子テーマの@importstyle.cssステートメントを使用して、生成されたページに次の順序があります。

  1. twentythirteen/genericons/genericons.css - >親テーマによってエンキュー
  2. child-theme/style.css - >親テーマによってエンキューされ、@ import 21/style.css
  3. 21/css/ie.css - >親テーマによってエンキュー
  4. child-theme/css/main.css - >子テーマによってエンキュー

親のstyle.cssmain.cssの依存関係としてエンキューすると、これは次のようになります。

  1. twentythirteen/genericons/genericons.css - >親テーマによってエンキュー
  2. child-theme/style.css - >空、親テーマによってエンキュー
  3. 21/css/ie.css - >親テーマによってエンキュー
  4. twentythirteen/style.css - >子テーマによってmain.cssの依存関係としてエンキュー
  5. child-theme/css/main.css - >子テーマによってエンキュー

Ie.cssが親テーマのstyle.cssの前に含まれていることに注意してください。親テーマのcssファイルのエンキュー順序を変更したくないのは、これがcssルールの優先順位に関する問題を引き起こさないとは思えないからです。

28
bernie

私の 前の回答 は非常に複雑で、親テーマの依存関係を尊重していない可能性があります(他の回答の注を参照)。

これは、はるかに簡単に動作するはずのもう1つのはるかに簡単な方法です。

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);

そのアイデアは、親テーマのget_stylesheet_uri()への呼び出しを単純にフィルタリングして、子テーマの代わりに独自のスタイルシートを返すことです。子テーマのスタイルシートは、後でアクションフックmy_theme_stylesにエンキューされます。

8
bernie

@importを使う必要はありません。実際にはしない方がいいでしょう。エンキューされたアプローチを使用することは、おそらく世界中でより良いでしょう。

これが、13のコードの関連部分です。

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' );

これがあなたのコードであなたがしていることです:

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' );

あなたのmain.cssが親のstyle.cssの後に来なければならないなら、あなたはそれをそれに依存するようにするだけです。

さて、あなたも子供の中にB.cssがあるのなら、それに応じて依存関係を設定します。

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' );

各項目に対して定義した依存関係を、それらの依存関係が実際に反映されていることを実際に反映するようにします。 main.cssがB.cssの後にくる必要がある場合は、それに依存します。 B.cssが親のstyle.cssの後にくる必要がある場合、Bはそれに依存します。エンキューシステムはあなたのためにそれを整理します。

そして、実際に子供のstyle.cssを使用していないのであれば、 それをエンキューする必要はまったくありません 。テーマのヘッダー情報を保持するための単なるプレースホルダーになることができます。使わない?ロードしないでください。

また、正確に何をしているのですか。 CSSはほとんどの場合ロード順を気にしません。 CSSはセレクターの特定性により依存しています。何かを上書きしたい場合は、それに対するセレクタをより具体的にします。それは最初、最後、またはその間にあるもののいずれでも、より具体的なセレクターが常に勝ちます。

編集

あなたのコメントを読み、コードを詳しく見ると、間違いがここにあるのがわかります。 13個のコードは "get_stylesheet_uri()"をエンキューしています。これは子テーマの場合は親のファイルではなく、子テーマのstyle.cssファイルになります。 @importが機能し、同じ順序を維持するのはそのためです(これもまた、あなたが思うほどには問題にならない)。

その場合、インポートを使用したくない場合は、親のstyle.cssを直接エンキューすることをお勧めします。そのようです:

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

子テーマのfunctions.phpのコードが最初に実行されるので、あなた自身のwp_enqueue_scriptsが最初に実行され、これは親テーマの自身が行っていないstyle.cssをエンキューするでしょう。親と同じように依存しないようにすることで、単純に正しく出力に入れられます。このファイルとgenericons.cssの順序は関係ありません。元の "13 - スタイル"にはgenericons.cssがリストされた依存関係として含まれていないためです。

あなた自身の子供のstyle.cssがロードされます、そして、正直なところ、これはあなたが別のmain.cssにではなく、子供のテーマのためにあなたの変更を入れるべきところです。あなたが自分の変更をそこに入れるのを妨げるものは何もありませんが、追加のcssファイルを持つ本当の理由はありません。

19
Otto

警告

この解決法は 親テーマの依存関係を尊重しない !親テーマのハンドル名を変更すると、親テーマに設定されている依存関係のチェーンに影響します。もっと簡単な 他の答え を見てください。

元の答え

Ottoの答えはかなり良いですが、私は私の子供のテーマのfunctions.phpでこれで終わりました

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);

子テーマのstyle.cssのバージョンを制御しながら、親テーマのstyle.cssの順序とバージョン番号を維持します。

2
bernie