it-swarm.com.ru

Управление версиями @import стиля родительской темы.

Контекст

Я построил детскую тему, основанную на Двадцать тринадцать, которая работает довольно хорошо. После обновления родительской темы до версии 1.3 я заметил странное поведение со стилем, вызванное кэшированной родительской темой style.css.

Вот содержимое style.css моей дочерней темы (без заголовков)

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

Таким образом, style.css дочерней темы не делает ничего, кроме импорта style.css родительской темы.

У меня также есть другой файл css с настройками моей дочерней темы, который я ставлю в очередь так в 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);

Это дает мне очень хороший URL-адрес CSS, например: domain.com/wp-content/themes/toutprettoutbon/css/main.css?ver=1.0.1, который обеспечивает перезагрузку таблицы стилей при обновлении дочерней темы.

Теперь проблема

Оператор @import url('../twentythirteen/style.css'); полностью независим от версии основной родительской темы. Фактически родительская тема может быть обновлена ​​без обновления дочерней темы, но браузеры по-прежнему будут использовать кэшированные версии старого ../twentythirteen/style.css.

Соответствующий код в Twenty Thirteen, который ставит в очередь 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' );

Я могу придумать несколько способов решения этой проблемы, но ни один из них не является действительно удовлетворительным:

  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 theme's style.css непосредственно со строкой версии. Это портит порядок очереди CSS в родительской теме.

  3. С помощью фильтра style_loader_tag измените сгенерированный тег css <link> для style.css и измените путь, чтобы он указывал непосредственно на parent theme's style.css со строкой версии. Кажется довольно неясным для такой распространенной необходимости (перебор кеша).

  4. Дамп исходной темы style.css в моей дочерней темы style.css. То же, что (1) на самом деле, но немного быстрее.

  5. Сделайте style.css моей дочерней темы символической ссылкой на style.css родительской темы. Это кажется довольно хакерским ...

Я что-то пропустил? Какие-либо предложения?

Правка

Добавлены таблицы стилей genericicons.css и ie.css в родительской теме, чтобы уточнить, почему я не могу изменить оператор @import css на wp_enqueue_style в моей дочерней теме. В настоящее время с оператором @import в style.css моей дочерней темы у меня есть такой порядок на сгенерированных страницах:

  1. fiftythirteen/genericons/genericons.css -> в родительской теме
  2. child-theme/style.css -> добавленный в родительскую тему, @imports fiftythirteen/style.css
  3. двадцать тринадцать/css/ie.css -> в родительской теме
  4. child-theme/css/main.css -> добавлена ​​в дочернюю тему

Если я поставлю в очередь style.css родителя как зависимость main.css, это станет:

  1. fiftythirteen/genericons/genericons.css -> в родительской теме
  2. child-theme/style.css -> пусто, поставлено в очередь родительской темой
  3. двадцать тринадцать/css/ie.css -> в родительской теме
  4. fiftythirteen/style.css -> добавлена ​​в дочернюю тему как зависимость от main.css
  5. child-theme/css/main.css -> добавлена ​​в дочернюю тему

Обратите внимание, что ie.css теперь включен перед style.css родительской темы. Я не хочу менять порядок постановки в очередь файлов css родительской темы, потому что не могу предположить, что это не вызовет проблем с приоритетом правил css.

28
bernie

Мой предыдущий ответ слишком сложен и потенциально не учитывает цепочку зависимостей родительской темы (см. Примечание в другом ответе).

Вот еще один гораздо более простой способ, который должен работать намного лучше:

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. На самом деле это лучше не делать. Использование поставленного в очередь подхода, вероятно, лучше всего вокруг.

Вот соответствующая часть двадцать тринадцатого кода:

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 больше зависит от специфики селекторов. Если вы хотите переопределить что-то, вы делаете свой селектор для этого более конкретным. Он может быть первым, последним или чем-то промежуточным, более конкретный селектор всегда побеждает.

Правка

Читая ваши комментарии и присматриваясь к коду, я вижу, в чем здесь ошибка. Двадцать тринадцать кодов ставит в очередь функцию "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, которую родительская тема не выполняет сама (потому что она фактически ставит в очередь style.css вашего ребенка). Не заставляя его зависеть ни от чего, так же как и от родителя, он просто корректно помещается в вывод. Обратите внимание, что порядок этого файла и genericons.css не имеет значения, потому что исходный "стиль в стиле двадцать тринадцати" не имеет genericons.css в качестве указанной зависимости.

Загрузится style.css вашего собственного ребенка, и, честно говоря, именно здесь вы должны поместить свои изменения для дочерней темы, а не в отдельный main.css. Ничто не мешает вам внести ваши изменения, но нет никакой реальной причины иметь дополнительный файл CSS.

19
Otto

предупреждение

Это решение не уважает зависимости родительской темы ! Изменение имени дескриптора родительской темы влияет на цепочку зависимостей, установленных в родительской теме. Смотрите мой гораздо более простой другой ответ .

оригинальный ответ

Хотя ответ Отто довольно хороший, я закончил с этим в функциях моей дочерней темы.

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