父主题的style.css的版本控制@import


28

语境

我根据《二十三岁》构建了一个儿童主题,效果很好。在将父主题更新为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');完全独立于基础父主题的版本。实际上,可以在不更新子主题的情况下更新父主题,但是浏览器仍将使用old的缓存版本../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过滤器修改<link>为其生成的css 标记,style.css并修改路径以直接指向主题的style.cssWITH版本字符串。对于这样的常见需求(高速缓存清除)而言似乎有些晦涩。

  4. 将父主题的主题转储到style.css我的子主题的主题中style.css。确实与(1)相同,但速度更快。

  5. 使我的子主题style.css成为父主题的符号链接style.css。这似乎有点骇人听闻...

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

编辑

新增genericicons.cssie.css父主题的样式表来解释,为什么我不能更改@importCSS语句wp_enqueue_style在我的子主题。目前,@import在子主题的声明中style.css,我在生成的页面中具有以下顺序:

  1. 23 / genericons / genericons.css->由父主题排队
  2. child-theme / style.css->由父主题排队,@ imports二十一十三/style.css
  3. 23 / css / ie.css->由父主题排队
  4. child-theme / css / main.css->按子主题排队

如果我将父级style.css作为的依赖项入队main.css,则它将变为:

  1. 23 / genericons / genericons.css->由父主题排队
  2. child-theme / style.css->空,由父主题排队
  3. 23 / css / ie.css->由父主题排队
  4. 21.13 / style.css->子主题作为main.css的依赖项入队
  5. child-theme / css / main.css->按子主题排队

注意,ie.css现在包括在父主题的之前style.css。我不想更改父主题的css文件的排队顺序,因为我无法假定这不会导致css规则优先级出现问题。


5
从不使用@import,而是将父主题的样式表设置为您自己样式表依赖项
fuxia

我知道这不是最好的方法,但建议在这里使用:codex.wordpress.org/Child_Themes
bernie 2014年

另外,按照您的建议进行操作也无法解决我的问题。父主题的位置style.css不会与现在相同。父级包含其他css文件,这些文件必须位于其style.css和我的子主题的css之间。
伯尼2014年

3
请完全忽略该法典。它充满了错误的信息。使用dependency参数将以正确的顺序包含样式表。
fuxia

请看我的编辑。
伯尼2014年

Answers:


19

您不必使用@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文件。


我完全同意,@imports不是最好的选择。请参阅我的“编辑”部分,以获取更精确的信息。关于CSS的订购,我没有任何特殊需求。我只是不想修改父主题的css文件的内部顺序,而这可能会导致css规则优先级出现问题。
伯尼2014年

需要说明的是,B.css(现在已更改为ie.css)不是我的子主题的一部分,而是实际上是父主题的一部分。
伯尼2014年

2
如果您希望样式紧随ie.css样式之后,则使自己的样式依赖于它。它的名字是“二十十三岁”。顺序完全由您声明的依赖项来管理,但是同样,对于CSS,它们在文档中的实际顺序通常并不重要,因此我不确定为什么您会过多地关心它。
奥托(Otto)

2
编辑了我的答案,以包括其他方法。
奥托

是的,我想我对保持CSS顺序的“需求”感到很困惑。如果顺序对于父主题确实非常重要,则应在依赖项中说明。
伯尼2014年

9

之前的答案过于复杂,可能不尊重父主题的依赖链(请参阅其他答案中的注释)。

这是另一个更简单的方法,应该可以更好地工作:

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()父主题中的调用,以返回其自己的样式表,而不是子主题的样式表。然后,将子主题的样式表放入action hook中my_theme_styles


仅作记录:1)您的代码将生成与使用旧@import版本完全相同的html ,对性能完全没有影响,将有两个单独的style.css请求服务器2)此答案将整个依赖项全部删除一起... 3)您可以检查什么get_template_directory_uriget_template_stylesheet_uri正在做的事情:core.trac.wordpress.org/browser/tags/4.8/src/wp-includes/...再次,不需要大部分代码。
bg17aw '17

1
@ bg17aw使用wp_enqueue_style?ver=2013-07-18根据主题的版本自动将缓存清除查询字符串添加到它生成的网址(例如)。这不是通过@import声明来完成的。
伯尼

2

警告

此解决方案不尊重父主题的依赖项!更改父主题的句柄名称会影响在父主题中设置的依赖项链。看看我更简单的其他答案

原始答案

尽管Otto的回答相当不错,但我最终在孩子主题的functions.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);

style.css在控制子主题的版本时,保持父主题的顺序和版本号style.css


5
令我感到困惑的是,最流行的博客软件仅需要20多行代码即可调整现有主题的CSS。我想那是工作安全。
卡尔·G

我必须更改[$parentNewHandle]array($parentNewHandle)
Carl G

@CarlG:PHP 5.4中引入了我使用的数组语法(括号)。
伯尼2015年

致支持者:请参阅我的其他答案,该答案可以解决此问题。
伯尼2015年

这都是一个巨大的误解,不需要任何这些。实际上,旧@import方法同样有效,请比较两种方法。至于子主题对父主题的依赖性,也不需要。style.css至少从我的测试来看,孩子总是在父母之后加载。爱被证明是错误的。
bg17aw '17
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.