Versiones de versiones @import of style.css del tema principal

27

Contexto

Construí un tema infantil basado en Twenty Thirteen que funciona bastante bien. Después de actualizar el tema principal a la versión 1.3, noté un comportamiento extraño con el estilo causado por el style.css de un tema principal en caché.

Aquí está el contenido de style.css del tema de mi hijo (omitiendo los encabezados)

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

Por lo tanto, style.css del tema secundario no hace nada más que importar el style.css del tema principal.

También tengo otro archivo css con las personalizaciones del tema de mi hijo, que encolado como en 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);

Esto me da una URL de css muy agradable como esta: domain.com/wp-content/themes/toutprettoutbon/css/main.css?ver=1.0.1 que se asegura de que la hoja de estilo se vuelva a cargar cuando se actualice el tema secundario.

Ahora el problema

La declaración @import url('../twentythirteen/style.css'); es completamente independiente de la versión del tema principal subyacente. De hecho, el tema principal se puede actualizar sin actualizar el tema secundario, pero los navegadores seguirán usando versiones en caché del antiguo ../twentythirteen/style.css .

Código relevante en Twenty Thirteen que pone en cola el 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' );

Puedo pensar en algunas maneras de resolver este problema, pero ninguna es realmente satisfactoria:

  1. Actualizar el tema de mi hijo cada vez que se actualice el tema principal para cambiar una cadena de versión en style.css (por ejemplo, @import url('../twentythirteen/style.css?ver=NEW_VERSION'); ). Esto crea un vínculo innecesario y molesto entre la versión del tema principal y el secundario.

  2. En functions.php de mi hijo, 1) wp_dequeue_style el tema secundario incluido style.css y 2) wp_enqueue_style el tema padre style.css directamente CON la cadena de versión. Esto desordena el orden de css en cola en el tema principal.

  3. Use el filtro style_loader_tag para modificar la etiqueta css <link> generada para style.css y modifique la ruta para que apunte directamente a la cadena padre style.css del tema CON una cadena de versión. Parece bastante oscuro para una necesidad tan común (almacenamiento en caché).

  4. Volcar style.css del tema principal en style.css del tema de mi hijo. Igual que (1) en realidad, pero un poco más rápido.

  5. Haga que style.css del tema de mi hijo sea un enlace simbólico al style.css del tema principal. Esto parece bastante hacker ...

¿Me he perdido algo? ¿Alguna sugerencia?

editar

Se agregaron las hojas de estilo genericicons.css y ie.css en el tema principal para aclarar por qué no puedo cambiar la instrucción @import css a wp_enqueue_style en el tema de mi hijo. Actualmente, con una declaración @import en style.css del tema de mi hijo, tengo este orden en las páginas generadas:

  1. veinte trece / genericons / genericons.css - > encolado por tema principal
  2. child-theme / style.css - > Encolado por tema principal, @imports twentythirteen / style.css
  3. veinte trece / css / ie.css - > encolado por tema principal
  4. child-theme / css / main.css - > encolado por tema infantil

Si encolaré style.css de los padres como una dependencia de main.css , esto se convertirá en:

  1. veinte trece / genericons / genericons.css - > encolado por tema principal
  2. child-theme / style.css - > vacío, encolado por tema principal
  3. veinte trece / css / ie.css - > encolado por tema principal
  4. veinte trece / style.css - > encolado por tema hijo como dependencia de main.css
  5. child-theme / css / main.css - > encolado por tema infantil

Tenga en cuenta que ie.css ahora se incluye antes de style.css del tema principal. No quiero cambiar el orden de puesta en cola de los archivos css del tema principal porque no puedo suponer que esto no causará problemas con la prioridad de las reglas de css.

    
pregunta bernie 03.10.2014 - 02:50

3 respuestas

8

Mi respuesta anterior es demasiado complicada y posiblemente no respeta la cadena de dependencia del tema principal (vea la nota en otra respuesta).

Aquí hay otra toma mucho más simple que debería funcionar mucho mejor:

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

La idea es simplemente filtrar la llamada a get_stylesheet_uri() en el tema principal para devolver su propia hoja de estilo en lugar de la del tema secundario. La hoja de estilo del tema secundario se pone en cola más adelante en el gancho de acción my_theme_styles .

    
respondido por el bernie 23.03.2015 - 18:13
19

No tienes que usar @import. Es mejor no hacerlo, en realidad. El uso de un enfoque en cola es probablemente mejor en todos los aspectos.

Aquí está la parte relevante del código de veinte trece:

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

Esto es lo que haces en tu 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' );

Si su main.css tiene que venir después del style.css de los padres, entonces usted solo depende de eso.

Ahora, si también tiene un B.css en el hijo, configure las dependencias en consecuencia:

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

Haga que las dependencias que defina para cada elemento reflejen realmente lo que realmente son esas dependencias. Si main.css debe venir después de B.css, entonces depende de ello. Si B.css debe venir después del style.css del padre, entonces B depende de eso. El sistema de encolado lo resolverá por usted.

Y si en realidad no está usando el style.css del niño para nada, entonces no tiene que ponerlo en la cola . Puede ser solo un marcador de posición para mantener la información del encabezado de tu tema. ¿No lo usas? No lo cargues.

Además, ¿qué está haciendo exactamente que depende tanto del pedido aquí? A CSS no le importa el orden de carga en la mayoría de las situaciones. CSS es más dependiente de la especificidad de los selectores. Si desea anular algo, haga que su selector sea más específico. Puede aparecer primero, o por último, o cualquier otra cosa, el selector más específico siempre gana.

Editar

Leyendo sus comentarios y mirando más de cerca el código, veo dónde está el error aquí. El código veinte y trece está encolando el "get_stylesheet_uri ()", que en un caso de tema secundario, sería el archivo style.css del tema de su hijo, no el archivo principal. Es por eso que @import funciona y sigue el mismo ordenamiento (lo cual, de nuevo, no importa tanto como usted cree).

En ese caso, si no desea utilizar la importación, recomendaría poner en cola el style.css de los padres directamente. Al igual que:

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

El código en las funciones.php del tema hijo se ejecuta primero, por lo que primero se ejecutarán tus propios wp_enqueue_scripts, y esto encolará el estilo.css del tema principal, que el tema principal no se está haciendo a sí mismo (porque en realidad es el estilo de tu hijo. css). Al no hacer que dependa de nada, igual que el padre, entonces simplemente se pone en la salida correctamente. Tenga en cuenta que el orden de este archivo y de genericons.css no importa, porque el "estilo veinte y trece" original no tiene genericons.css como una dependencia listada.

El estilo.css de su propio hijo se cargará, y honestamente, aquí es donde debe colocar los cambios para el tema del niño, no en un main.css separado. No hay nada que le impida colocar los cambios allí, pero no hay ninguna razón real para tener un archivo css adicional.

    
respondido por el Otto 03.10.2014 - 19:25
2

advertencia

Esta solución no respeta las dependencias del tema principal ! Cambiar el nombre del identificador del tema principal afecta a la cadena de dependencias establecida en el tema principal. Consulte mi mucho más simple otra respuesta .

respuesta original

Aunque la respuesta de Otto es bastante buena, terminé con esto en las funciones de mi hijo tema.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);

Mantiene el número de orden y el número de versión de style.css del tema principal mientras controla la versión de style.css del tema principal.

    
respondido por el bernie 06.10.2014 - 20:25

Lea otras preguntas en las etiquetas