将 WordPress 子主题样式表排入队列时正确的方法新样式会覆盖父样式。
但是,由于 Divi 引入了对自定义帖子类型的 Builder 支持,因此添加了新的样式表 style-cpt.css。
此样式表中的所有样式(不幸的是,其中很多样式后面都有
!important
)都是在排队的子样式之后声明的,因此将覆盖任何匹配的样式。
有什么方法可以覆盖这种“自定义”样式表吗?
“remove_action(...);”自 Divi 版本 4.10.6(21 年 9 月)起,解决方案不再有效,因为“et_divi_replace_stylesheet”操作已被删除。
我解决这个问题的方法是覆盖 Divi/includes/builder/core.php 中的第 #776 行(从版本 4.14.6 开始),以便函数 et_builder_should_wrap_styles() 始终返回 false:
function et_builder_should_wrap_styles() {
static $should_wrap = null;
if ( null === $should_wrap ) {
$post_id = get_the_ID();
// Warp on custom post type archives and on non-native custom post types when the builder is used.
$should_wrap = et_builder_is_custom_post_type_archive() || ( et_builder_post_is_of_custom_post_type( $post_id ) && et_pb_is_pagebuilder_used( $post_id ) );
}
// return $should_wrap; /*** ORIGINAL CODE ***/
return false; /*** NEW CODE ***/
}
然后,为了确保 Divi 更新时我不会丢失此编辑,我设置了一个操作,以便在每次 Divi 更新发生时自动重写此行:
add_action('upgrader_process_complete', 'edit_files_on_update', 10, 2);
function edit_files_on_update($upgrader_object, $hook_extra) {
if ($hook_extra['action'] !== 'update') return false;
if ($hook_extra['type'] === 'theme' && isset($hook_extra['themes'])) {
// Divi - disable CPT CSS wrapper
if (array_search('Divi', $hook_extra['themes']) !== false) {
$file_location = get_template_directory().'/includes/builder/core.php';
$file_contents = file_get_contents($file_location);
$file_contents = str_replace('return $should_wrap;', 'return false;', $file_contents);
file_put_contents($file_location, $file_contents);
}
}
}
我知道编辑主题的原始文件在技术上是不正确的,但“正确”的替代方案是覆盖我的子主题中的整个 Divi/includes/builder/core.php 文件,该文件有 7253 行长!未来的 Divi 更新很有可能会编辑该原始文件,从而使我无法在子主题版本中反映出这些编辑。
我正在使用这个并且工作正常:
function disable_cptdivi(){
remove_action( 'wp_enqueue_scripts', 'et_divi_replace_stylesheet', 99999998 ); } add_action('init', 'disable_cptdivi');
经过一些实验,我发现functions.php中的以下代码可以工作...(请注意,这会将标准主题样式表以及Divi的自定义后子主题放入队列)。 您可以在子主题文件夹中的自己的 style-cpt.css 文件中包含要覆盖的所有样式。
function my_theme_enqueue_styles() {
$parent_style = 'divi-style';
$template_directory = get_template_directory_uri();
$stylesheet_directory = get_stylesheet_directory_uri();
wp_enqueue_style( $parent_style, $template_directory . '/style.css' );
wp_enqueue_style( 'child-style',
$stylesheet_directory . '/style.css',
array( $parent_style ),
wp_get_theme()->get('Version')
);
$parent_style = 'divi-cpt-style';
wp_enqueue_style( $parent_style, $template_directory . '/style-cpt.css' );
wp_enqueue_style( 'child-cpt-style',
$stylesheet_directory . '/style-cpt.css',
array( $parent_style ),
wp_get_theme()->get('Version')
);
}
add_action( 'wp_enqueue_scripts', 'my_theme_enqueue_styles' );
参加聚会已经很晚了,但我通过在主题选项中的自定义 CSS 中添加 #page-container 选择器来阻止 Divi 的 CPT 样式,例如:
.header --> #page-container .header
#nav_toggle --> #page-container #nav_toggle
将覆盖 #et-boc 选择器
使用 Divi 6.1.1 进行测试
我有一个类似的问题,但内联生成的CSS仍然包含包装器,所以我不得不升级@Weekend32答案:
我通过更新 Divi/includes/builder/core.php 中的第 6701 行来删除生成的内联 css 中所有与 cpt 相关的包装器
function et_builder_maybe_wrap_css_selector( $selector, $suffix = '', $clone = true, $inside_selectors = '' ) {
static $should_wrap_selectors = array();
$post_id = ET_Builder_Element::get_theme_builder_layout_id();
if ( ! isset( $should_wrap_selectors[ $post_id ] ) ) {
$is_builder_used = et_pb_is_pagebuilder_used( $post_id ) || has_block( 'divi/layout', get_the_ID() );
/*** ORIGINAL CODE ***/
//$should_wrap_selectors[ $post_id ] = et_is_builder_plugin_active() || et_builder_is_custom_post_type_archive() || ( $is_builder_used && ( et_builder_post_is_of_custom_post_type( $post_id ) || et_theme_builder_is_layout_post_type( get_post_type( $post_id ) ) ) );
/*** END ORIGINAL CODE ***/
/*** NEW CODE ***/
$should_wrap_selectors[ $post_id ] = false;
/*** END NEW CODE ***/
}
/*** HERE IS A LOT MORE CODE IN THE ORIGINAL FILE ***/
return trim( $result );
}
所以我也更新了 ChildTheme/Function.php 更新脚本:
/**
* Disable new divi cpt style wraper
* https://stackoverflow.com/questions/53474232/wordpress-how-to-override-divis-custom-post-type-stylesheet
**/
add_action('upgrader_process_complete', 'edit_files_on_update', 10, 2);
function edit_files_on_update($upgrader_object, $hook_extra) {
if ($hook_extra['action'] !== 'update') return false;
if ($hook_extra['type'] === 'theme' && isset($hook_extra['themes'])) {
// Divi - disable CPT CSS wrapper
if (array_search('Divi', $hook_extra['themes']) !== false) {
$file_location = get_template_directory().'/includes/builder/core.php';
$file_contents = file_get_contents($file_location);
$file_contents = str_replace('return $should_wrap;', 'return false;', $file_contents);
/*** ADDED LINE ***/
$file_contents = str_replace('$should_wrap_selectors[ $post_id ] = et_is_builder_plugin_active() || et_builder_is_custom_post_type_archive() || ( $is_builder_used && ( et_builder_post_is_of_custom_post_type( $post_id ) || et_theme_builder_is_layout_post_type( get_post_type( $post_id ) ) ) );', '$should_wrap_selectors[ $post_id ] = false;', $file_contents);
file_put_contents($file_location, $file_contents);
}
}
}
经过一整天的尝试不同的解决方案,我发现在Divi主题中,在
Divi/includes/builder/core.php
下,有一个包含et_builder_get_default_post_types()
的函数apply_filter('et_builder_default_post_types')
,可以在你的子主题的functions.php中使用。这是函数:
/**
* Get the supported post types by default.
*
* @since 3.10
*
* @return string[]
*/
function et_builder_get_default_post_types() {
/**
* Filter default post types that are powered by the builder.
*
* @since 4.0
*
* @param string[]
*/
return apply_filters(
'et_builder_default_post_types',
array(
// WordPress.
'page',
'post',
// Divi/Extra/DBP.
'project',
'et_pb_layout',
)
);
}
因此,基本上,您必须将自定义帖子类型定义为默认帖子类型,并且“-cpt”后缀将被删除。 以下是自定义帖子类型“产品”、“服务”和“事件”的示例:
add_filter('et_builder_default_post_types', function($post_types) {
$post_types[] = 'product';
$post_types[] = 'service';
$post_types[] = 'event';
return $post_types;
});
简单的解决方案,无需编辑 Divi 主题文件即可工作。希望它也适合你。