Versioning @import do estilo do tema pai.css

27

Contexto

Eu criei um tema infantil baseado no Twenty Thirteen, que funciona muito bem. Depois de atualizar o tema pai para a versão 1.3, notei um comportamento estranho com o estilo que foi causado por um tema pai armazenado em cache style.css .

Aqui está o conteúdo do meu tema filho: style.css (omitindo cabeçalhos)

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

Portanto, o tema filho style.css não faz nada além de importar o style.css do tema pai.

Eu também tenho outro arquivo css com as personalizações do meu tema filho, que enfileiro assim em 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);

Isso me dá uma URL muito boa, como esta: domain.com/wp-content/themes/toutprettoutbon/css/main.css?ver=1.0.1 , que garante que a folha de estilo seja recarregada quando o tema filho for atualizado.

Agora o problema

A instrução @import url('../twentythirteen/style.css'); é completamente independente da versão do tema pai subjacente. Na verdade, o tema pai pode ser atualizado sem atualizar o tema filho, mas os navegadores ainda usarão versões em cache do antigo ../twentythirteen/style.css .

Código relevante no Vigésimo Terceiro que enfileira o 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' );

Posso pensar em algumas maneiras de resolver esse problema, mas nenhuma é realmente satisfatória:

  1. Atualize meu tema filho toda vez que o tema pai for atualizado para alterar uma string de versão em style.css (por exemplo, @import url('../twentythirteen/style.css?ver=NEW_VERSION'); ). Isso cria um link desnecessário e irritante entre a versão do tema pai e o filho.

  2. No meu filho functions.php , 1) wp_dequeue_style o tema filho incluído style.css e 2) wp_enqueue_style o tema pai style.css diretamente com a string de versão. Isso atrapalha a ordem do css enfileirado no tema pai.

  3. Use o filtro style_loader_tag para modificar a tag css <link> gerada para style.css e modificar o caminho para apontar diretamente para a string% version dostyle.css WITH do pai . Parece bastante obscuro para uma necessidade tão comum (impedimento de cache).

  4. Descarregue style.css do tema pai no style.css do meu tema filho. O mesmo que (1) realmente, mas um pouco mais rápido.

  5. Torne o tema do meu filho igual a style.css um link simbólico para o style.css do tema pai. Isso parece bastante hackish ...

Eu perdi alguma coisa? Alguma sugestão?

editar

Adicionadas as folhas de estilo genericicons.css e ie.css no tema pai para esclarecer por que não posso alterar a instrução @import css para wp_enqueue_style no meu tema filho. Atualmente, com uma instrução @import no style.css de meu filho, eu tenho esse pedido em páginas geradas:

  1. twentythirteen / genericons / genericons.css - > enfileirado pelo tema pai
  2. child-theme / style.css - > enfileirado pelo tema pai, @imports twentythirteen / style.css
  3. twentythirteen / css / ie.css - > enfileirado pelo tema pai
  4. child-theme / css / main.css - > enfileirado pelo tema filho

Se eu enfileirar o style.css do pai como uma dependência de main.css , isso se tornará:

  1. twentythirteen / genericons / genericons.css - > enfileirado pelo tema pai
  2. child-theme / style.css - > vazio, enfileirado pelo tema pai
  3. twentythirteen / css / ie.css - > enfileirado pelo tema pai
  4. twentythirteen / style.css - > enfileirado pelo tema filho como dependência de main.css
  5. child-theme / css / main.css - > enfileirado pelo tema filho

Observe que o ie.css agora está incluído antes do style.css do tema pai. Eu não quero alterar a ordem de enfileiramento dos arquivos css do tema pai, porque eu não posso presumir que isso não causará problemas com a prioridade das regras css.

    
por bernie 03.10.2014 / 02:50
fonte

3 respostas

8

Minha resposta anterior é excessivamente complicada e potencialmente não respeita a cadeia de dependências do tema pai (veja nota em outra resposta).

Aqui está outro exemplo muito mais simples que deve funcionar muito melhor:

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

A idéia é simplesmente filtrar a chamada para get_stylesheet_uri() no tema pai para retornar sua própria folha de estilo em vez do tema filho. A folha de estilo do tema filho é então enfileirada posteriormente no gancho de ação my_theme_styles .

    
por bernie 23.03.2015 / 18:13
fonte
19

Você não precisa usar o @import. É melhor não, na verdade. Usar uma abordagem enfileirada provavelmente é melhor ao redor.

Aqui está a parte relevante do código do vigésimo-sétimo:

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

Veja o que você faz no seu código:

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

Se o seu main.css tiver que vir depois do style.css do pai, então você só depende disso.

Agora, se você também tiver um B.css no filho, configure as dependências de acordo:

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

Torne as dependências que você define para cada item refletindo de fato quais são essas dependências. Se main.css deve vir depois de B.css, então depende disso. Se o B.css deve vir depois do style.css do pai, então B depende disso. O sistema de enfileiramento irá resolver isso para você.

E se você não estiver realmente usando o style.css da criança para nada, então você não precisará enfileirá-lo . Pode ser apenas um espaço reservado para armazenar as informações de cabeçalho do seu tema. Não está usando? Não carregue.

Além disso, o que você está fazendo exatamente é tão dependente da encomenda aqui? O CSS não se preocupa com a ordem de carregamento na maioria das situações. CSS é mais dependente da especificidade dos seletores. Se você quiser substituir algo, você faz o seu seletor para ele mais específico. Pode vir primeiro, ou por último, ou qualquer coisa no meio, o seletor mais específico sempre ganha.

Editar

Lendo seus comentários e olhando mais de perto o código, vejo onde está o erro. O código vinte e treze está enfileirando o "get_stylesheet_uri ()", que em um caso de tema filho, seria o arquivo style.css do seu tema filho, não o arquivo do pai. É por isso que o @import funciona e mantém a mesma ordem (o que, de novo, não importa tanto quanto você pensa).

Nesse caso, se você não quiser usar a importação, recomendo que enfileire o style.css do pai diretamente. Assim:

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

O código em functions.php do tema filho é executado primeiro, portanto seus próprios wp_enqueue_scripts serão executados primeiro, e isso enfileiraçará o style.css do tema pai, que o tema pai não está fazendo por si próprio (porque está enfileirando o estilo do seu filho. css). Por não fazê-lo depender de nada, mesmo que o pai, ele simplesmente é colocado na saída corretamente. Observe que a ordem deste arquivo e o genericons.css não importam, porque o "twentythirteen-style" original não tem o genericons.css como uma dependência listada.

O style.css do seu próprio filho será carregado e, honestamente, é aqui que você deve colocar as alterações para o tema filho, não para um arquivo main.css separado. Não há nada que impeça você de colocar suas alterações lá, mas não há nenhum motivo real para ter um arquivo css extra.

    
por Otto 03.10.2014 / 19:25
fonte
2

aviso

Esta solução não respeita as dependências do tema pai ! Alterar o nome do manipulador do tema pai afeta a cadeia de dependências configurada no tema pai. Veja minha resposta muito mais simples outra resposta .

resposta original

Embora a resposta de Otto seja muito boa, acabei com isso nas funções do meu filho.

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

Ele mantém os números de versão e pedidos de style.css do tema pai enquanto controla a versão do tema filho style.css .

    
por bernie 06.10.2014 / 20:25
fonte