Versioning @import du style.css du thème parent

27

Contexte

J'ai construit un thème pour enfants basé sur Twenty Thirteen qui fonctionne assez bien. Après la mise à jour du thème parent vers la version 1.3, j'ai constaté un comportement étrange avec le style provoqué par le style.css d'un thème parent mis en cache.

Voici le contenu du style.css de mon thème enfant (sans en-tête)

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

Ainsi, le style.css du thème enfant ne fait rien d’importer que d’importer le style.css du thème parent.

J'ai également un autre fichier CSS avec les personnalisations de mon thème enfant que je mets en file d'attente comme dans 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);

Cela me donne une très belle URL css comme celle-ci: domain.com/wp-content/themes/toutprettoutbon/css/main.css?ver=1.0.1 qui assure que la feuille de style est rechargée lorsque le thème enfant est mis à jour.

Maintenant le problème

La déclaration @import url('../twentythirteen/style.css'); est complètement indépendante de la version du thème parent sous-jacent. En fait, le thème parent peut être mis à jour sans mettre à jour le thème enfant, mais les navigateurs continueront d'utiliser les versions en cache de l'ancien ../twentythirteen/style.css .

Code pertinent dans Twenty Treize qui met en file d'attente le 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' );

Je peux penser à quelques solutions pour résoudre ce problème, mais aucune n’est vraiment satisfaisante:

  1. Mettez à jour mon thème enfant chaque fois que le thème parent est mis à jour pour modifier une chaîne de version dans style.css (par exemple, @import url('../twentythirteen/style.css?ver=NEW_VERSION'); ). Cela crée un lien inutile et gênant entre la version du thème parent et l’enfant.

  2. Dans functions.php de mon enfant, 1) wp_dequeue_style style.css du thème de l'enfant inclus et 2) wp_enqueue_style le% strong parent du thème > inclus. Cela perturbe l'ordre des CSS en file d'attente dans le thème parent.

  3. Utilisez le filtre style.css pour modifier le tag généré css style_loader_tag pour <link> et modifiez le chemin pour qu'il pointe directement vers le parent style.css du thème avec une chaîne de version. Cela semble assez obscur pour un besoin aussi commun (contournement du cache).

  4. Videz le style.css du thème parent dans le style.css de mon thème enfant. Identique à (1) vraiment, mais un peu plus rapide.

  5. Faites en sorte que le style.css de mon thème enfant soit un lien symbolique vers le style.css du thème parent. Cela semble assez bidon ...

Ai-je oublié quelque chose? Des suggestions?

modifier

Ajout des feuilles de style style.css et genericicons.css dans le thème parent afin de préciser pourquoi je ne peux pas modifier l'instruction ie.css css en @import dans le thème de mon enfant. Actuellement, avec une déclaration wp_enqueue_style dans le @import de mon thème enfant, j'ai cet ordre dans les pages générées:

  1. vingt-treize / genericons / genericons.css - > mis en file d'attente par thème parent
  2. child-theme / style.css - > mis en file d'attente par thème parent, @imports twentythirteen / style.css
  3. vingt-treize / css / ie.css - > mis en file d'attente par thème parent
  4. thème-enfant / css / main.css - > mis en file d'attente par thème enfant

Si je mets en file d'attente le style.css du parent en tant que dépendance de style.css , cela devient:

  1. vingt-treize / genericons / genericons.css - > mis en file d'attente par thème parent
  2. child-theme / style.css - > vide, mis en file d'attente par thème parent
  3. vingt-treize / css / ie.css - > mis en file d'attente par thème parent
  4. vingt-treize / style.css - > mis en file d'attente par thème enfant en tant que dépendance de main.css
  5. thème-enfant / css / main.css - > mis en file d'attente par thème enfant

Notez que ie.css est maintenant inclus avant le main.css du thème parent. Je ne souhaite pas modifier l'ordre de mise en file d'attente des fichiers CSS du thème parent, car je ne peux pas présumer que cela ne posera pas de problème avec la priorité des règles CSS.

    
posée bernie 03.10.2014 - 02:50

3 réponses

8

Ma réponse précédente est trop compliquée et ne respecte potentiellement pas la chaîne de dépendance du thème parent (voir la remarque dans autre réponse).

Voici une autre prise beaucoup plus simple qui devrait fonctionner beaucoup mieux:

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

L'idée est simplement de filtrer l'appel à get_stylesheet_uri() dans le thème parent pour renvoyer sa propre feuille de style à la place de celle du thème enfant. La feuille de style du thème enfant est ensuite mise en file d'attente dans le crochet d'action my_theme_styles .

    
réponse donnée bernie 23.03.2015 - 18:13
19

Vous n'êtes pas obligé d'utiliser @import. En fait, il vaut mieux ne pas le faire. Utiliser une approche en file d'attente est probablement préférable dans tous les cas.

Voici la partie pertinente du code de vingt-treize ans:

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

Voici ce que vous faites dans votre code:

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

Si votre fichier main.css doit précéder le fichier style.css du parent, il vous suffit de le rendre dépendant de cela.

Maintenant, si vous avez également un fichier B.css dans l'enfant, vous configurez les dépendances en conséquence:

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

Faites en sorte que les dépendances que vous définissez pour chaque élément reflètent réellement ce qu’elles sont réellement. Si main.css doit venir après B.css, alors cela dépend. Si B.css doit venir après style.css du parent, alors B en dépend. Le système de mise en file d'attente le réglera pour vous.

Et si vous n'utilisez réellement pas le style.css de l'enfant pour quoi que ce soit, alors vous n'avez pas besoin de le mettre en file d'attente . Il peut s'agir simplement d'un espace réservé pour contenir les informations d'en-tête de votre thème. Ne pas l'utiliser? Ne le chargez pas.

De plus, que faites-vous au juste, qui dépend tellement de la commande ici? CSS ne se soucie pas de l'ordre de chargement dans la plupart des situations. CSS dépend davantage de la spécificité des sélecteurs. Si vous souhaitez remplacer quelque chose, vous définissez votre sélecteur pour plus de précision. Cela peut venir en premier, ou en dernier lieu, ou quelque chose entre les deux, le sélecteur le plus spécifique gagne toujours.

Modifier

En lisant vos commentaires et en regardant de plus près le code, je vois où se trouve l’erreur. Le code vingt-treize met en file d'attente "get_stylesheet_uri ()", qui dans le cas d'un thème de thème enfant serait le fichier style.css de votre thème enfant, et non le fichier parent. C’est pourquoi @import fonctionne et conserve le même ordre (ce qui encore une fois importe peu).

Dans ce cas, si vous ne souhaitez pas utiliser l'importation, je vous recommande de mettre directement en file d'attente le fichier style.css du parent. Comme si:

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

Le code dans functions.php du thème enfant s'exécute en premier. Par conséquent, votre propre script wp_enqueue_scripts sera exécuté en premier, ce qui mettra en file d'attente le style.css du thème parent, que le thème parent ne fait pas lui-même (car il met en file d'attente le style de votre enfant. css). En ne le faisant pas dépendre de quoi que ce soit, comme le parent, il est simplement placé correctement dans la sortie. Notez que l'ordre de ce fichier et de genericons.css n'a pas d'importance, car le "style de vingt-deux ans" d'origine n'a pas le genericics.css en tant que dépendance répertoriée.

Le fichier style.css de votre propre enfant sera chargé, et honnêtement, c’est là que vous devriez placer vos modifications pour le thème enfant, et non dans un fichier principal.css séparé. Rien ne vous empêche de mettre vos modifications ici, mais il n’ya aucune raison d’avoir un fichier CSS supplémentaire.

    
réponse donnée Otto 03.10.2014 - 19:25
2

avertissement

Cette solution ne ne respecte pas les dépendances du thème parent . ! La modification du nom de descripteur du thème parent affecte la chaîne de dépendances définie dans le thème parent. Voir ma autre réponse plus simple .

réponse originale

Bien que la réponse d’Otto soit plutôt bonne, j’ai fini avec cela dans le functions.php de mon thème enfant

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

Il conserve la commande style.css du thème parent et les numéros de version tout en contrôlant la version de style.css du thème enfant.

    
réponse donnée bernie 06.10.2014 - 20:25

Lire d'autres questions sur les étiquettes