问题描述

Context

我建立了一个基于二十三十三的小孩主题,效果很好。将父主题更新为 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);

这给我一个非常好的 css 网址,如下所示:domain.com/wp-content/themes/toutprettoutbon/css/main.css?ver=1.0.1,确保样式表在子主题更新时重新加载。

现在的问题

声明 @import url('../twentythirteen/style.css'); 完全独立于底层父主题版本。实际上,可以更新父主题而不更新子主题,但浏览器仍将使用旧的../twentythirteen/style.css 的缓存版本。

二十三十进入 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 的父主题的 style.css 直接与版本字符串。这使得父主题中排队的 css 的顺序变得混乱。

  3. 使用 style_loader_tag 过滤器修改 style.css 生成的 css <link> 标签,并修改路径以直接指向父主题的 style.css 与版本字符串。似乎对于这样一个常见的需求 (缓存破坏) 似乎是模糊的。

  4. 在我的孩子主题的 style.css 中转储父主题的 style.css 。与 (1) 相同,但是要快一点。

  5. 让我的孩子主题的 style.css 成为父主题的 style.css 的符号链接。这似乎相当黑客

我错过了什么吗?有什么建议么?

edit

在父主题中添加了 genericicons.cssie.css 样式表,以澄清为什么我不能将 @import css 语句更改为 wp_enqueue_style 在我的小孩主题中。目前,在我的小孩主题 style.css 中有一个 @import 语句,我在生成的页面中有这个命令:

  1. 二十三/genericons /genericons.css – > 由父母排队

  2. child-theme /style.css – > 由父主题排出,@imports 二十三/style.css

  3. 二十三/css /ie.css – > 由父母排队

  4. child-theme /css /main.css – > 以小孩主题排队

如果我排队父母的 style.css 作为 main.css 的依赖,这将成为:

  1. 二十三/genericons /genericons.css – > 由父母排队

  2. child-theme /style.css – > 空,由父主题排队

  3. 二十三/css /ie.css – > 由父母排队

  4. 二十三/style.css – > 由 child.css 作为依赖关系引导

  5. child-theme /css /main.css – > 以小孩主题排队

请注意,ie.css 现在包含在父主题 style.css 之前。我不想改变父主题的 css 文件的排队顺序,因为我不能假定这不会导致 CSS 优先级的问题。

最佳解决方案

您不必使用 @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 更依赖于选择器的特异性。如果你想要覆盖某些东西,你可以选择它更具体。它可以先到,最后,或之间的任何东西,更具体的选择器总是胜利。

编辑

阅读您的意见并仔细阅读代码,我看到错误在这里。 twenty-thirteen 代码是插入”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 的顺序并不重要,因为原始的”twentythirteen-style” 没有 genericons.css 作为列出的依赖项。

你自己的孩子的 style.css 将加载,老实说,这是你应该把你的更改为孩子主题,而不是单独的 main.css 。没有什么可以阻止你把你的改变放在那里,但没有什么真正的理由有一个额外的 css 文件。

次佳解决方案

我的 previous answer 过于复杂,可能不尊重父主题的依赖关系链 (见其他答案中的说明) 。

这是另一个更简单的做法,应该工作得更好:

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 中排队。

参考文献

注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。