各位观众,晚上好!今天咱们来聊聊 WordPress 里一个挺重要的函数,is_gutenberg_page()
。这玩意儿关乎你 WordPress 站点编辑体验,以及插件、主题对 Gutenberg 编辑器的兼容性。 别看名字挺长,理解了它背后的逻辑,就能让你在自定义 WordPress 时少走很多弯路。
一、Gutenberg 编辑器是啥?
首先,咱们得先搞清楚 Gutenberg 是个啥。简单来说,Gutenberg 是 WordPress 5.0 版本引入的块编辑器,它彻底改变了 WordPress 的内容编辑方式。以前咱们用的是经典编辑器(TinyMCE),就像用 Word 写文章一样。但 Gutenberg 把文章内容拆分成一个个独立的“块”,比如段落块、图片块、标题块等等。你可以像搭积木一样,自由组合这些块来创建页面和文章。
二、is_gutenberg_page()
函数的作用
is_gutenberg_page()
的作用,就是判断当前页面是否正在使用 Gutenberg 编辑器。这个判断对于插件开发者尤其重要。比如,你的插件可能需要根据用户使用的编辑器类型,加载不同的 CSS 样式或 JavaScript 代码。
三、源码解析:is_gutenberg_page()
究竟做了什么?
废话不多说,咱们直接上代码,扒一扒 is_gutenberg_page()
的源码。(以下代码基于 WordPress 6.x 版本)
<?php
/**
* Checks if the current page is using the Gutenberg editor.
*
* @since 5.0.0
*
* @global string $pagenow The filename of the current screen.
* @global WP_Screen $current_screen The current screen.
*
* @return bool True if the current page is using the Gutenberg editor, false otherwise.
*/
function is_gutenberg_page() {
global $pagenow, $current_screen;
if ( ! function_exists( 'use_block_editor_for_post_type' ) ) {
require_once ABSPATH . 'wp-admin/includes/post.php';
}
// Avoid errors when processing AJAX requests or running cron.
if ( ! isset( $current_screen ) ) {
return false;
}
// Allow the use of the block editor, regardless of user settings,
// if the user has the 'edit_posts' capability and the query string
// contains 'force-reusable-blocks-editor'.
if (
current_user_can( 'edit_posts' ) &&
! empty( $_GET['force-reusable-blocks-editor'] )
) {
return true;
}
$block_editor = false;
// Gutenberg is not available for the 'site-health' tool.
if ( 'site-health.php' === $pagenow ) {
return false;
}
if ( 'post.php' === $pagenow || 'post-new.php' === $pagenow ) {
$post_type = $current_screen->post_type;
if ( use_block_editor_for_post_type( $post_type ) ) {
$block_editor = true;
}
} elseif ( 'widgets.php' === $pagenow ) {
$block_editor = true;
} elseif ( 'site-editor.php' === $pagenow ) {
$block_editor = true;
} elseif ( 'themes.php' === $pagenow && isset( $_GET['gutenberg-edit-site'] ) ) {
$block_editor = true;
} elseif ( 'wp-login.php' === $pagenow ) {
$block_editor = false;
}
/**
* Filters whether the current page is using the Gutenberg editor.
*
* @since 5.0.0
*
* @param bool $block_editor Whether the current page is using the Gutenberg editor.
*/
return apply_filters( 'use_block_editor_for_post', $block_editor );
}
好,咱们一行行来解读:
-
全局变量引入:
global $pagenow, $current_screen;
这行代码引入了两个全局变量:
$pagenow
和$current_screen
。$pagenow
:表示当前页面的文件名,比如post.php
(编辑文章页面)、post-new.php
(新建文章页面)等。$current_screen
:是一个WP_Screen
类的实例,包含了当前屏幕的信息,比如 post type(文章类型)、base(页面基础名)等。
-
use_block_editor_for_post_type()
函数检查:if ( ! function_exists( 'use_block_editor_for_post_type' ) ) { require_once ABSPATH . 'wp-admin/includes/post.php'; }
这段代码首先检查
use_block_editor_for_post_type()
函数是否存在。如果不存在,就引入wp-admin/includes/post.php
文件,这个文件定义了该函数。use_block_editor_for_post_type()
函数用于判断指定的文章类型是否启用了 Gutenberg 编辑器。 -
避免 AJAX 和 Cron 错误:
if ( ! isset( $current_screen ) ) { return false; }
在 AJAX 请求或 Cron 任务中,
$current_screen
可能未被设置,为了避免出现错误,直接返回false
。 -
强制启用 Gutenberg 编辑器 (通过查询字符串):
if ( current_user_can( 'edit_posts' ) && ! empty( $_GET['force-reusable-blocks-editor'] ) ) { return true; }
如果当前用户有编辑文章的权限,并且 URL 查询字符串中包含
force-reusable-blocks-editor
参数,则强制启用 Gutenberg 编辑器,并返回 true. -
$block_editor
变量初始化:$block_editor = false;
初始化一个
$block_editor
变量,默认值为false
,表示默认情况下不使用 Gutenberg 编辑器。 -
针对特定页面的判断:
// Gutenberg is not available for the 'site-health' tool. if ( 'site-health.php' === $pagenow ) { return false; } if ( 'post.php' === $pagenow || 'post-new.php' === $pagenow ) { $post_type = $current_screen->post_type; if ( use_block_editor_for_post_type( $post_type ) ) { $block_editor = true; } } elseif ( 'widgets.php' === $pagenow ) { $block_editor = true; } elseif ( 'site-editor.php' === $pagenow ) { $block_editor = true; } elseif ( 'themes.php' === $pagenow && isset( $_GET['gutenberg-edit-site'] ) ) { $block_editor = true; } elseif ( 'wp-login.php' === $pagenow ) { $block_editor = false; }
这部分代码是核心逻辑,它根据不同的
$pagenow
值,判断是否使用 Gutenberg 编辑器。site-health.php
:站点健康工具页面,禁用 Gutenberg 编辑器。post.php
和post-new.php
:编辑和新建文章页面。首先获取当前文章类型$post_type
,然后调用use_block_editor_for_post_type()
函数判断该文章类型是否启用了 Gutenberg 编辑器。widgets.php
:小工具页面,使用 Gutenberg 编辑器(块小工具编辑器)。site-editor.php
: 站点编辑器页面(古腾堡全站编辑),使用 Gutenberg 编辑器。themes.php
: 主题页面,需要get参数gutenberg-edit-site
存在时,使用 Gutenberg 编辑器。wp-login.php
: 登录页面,禁用 Gutenberg 编辑器。
-
apply_filters()
过滤器:return apply_filters( 'use_block_editor_for_post', $block_editor );
最后,使用
apply_filters()
函数,允许开发者通过use_block_editor_for_post
过滤器来修改$block_editor
的值。这提供了极大的灵活性,开发者可以根据自己的需求,自定义 Gutenberg 编辑器的启用逻辑。
四、use_block_editor_for_post_type()
函数
上面提到了 use_block_editor_for_post_type()
函数,咱们也简单看一下它的实现:
<?php
/**
* Determines whether the block editor is enabled for the given post type.
*
* @since 5.0.0
*
* @param string $post_type The post type to check.
*
* @return bool True if the block editor is enabled for the given post type, false otherwise.
*/
function use_block_editor_for_post_type( $post_type ) {
if ( ! post_type_exists( $post_type ) ) {
return false;
}
/**
* Filters whether the block editor is enabled for the given post type.
*
* @since 5.0.0
*
* @param bool $use_block_editor Whether the block editor is enabled.
* @param string $post_type The post type being checked.
*/
return apply_filters(
'use_block_editor_for_post_type',
post_type_supports( $post_type, 'editor' ),
$post_type
);
}
这个函数主要做了两件事:
-
判断文章类型是否存在:
if ( ! post_type_exists( $post_type ) ) { return false; }
如果指定的文章类型不存在,直接返回
false
。 -
判断文章类型是否支持
editor
特性:return apply_filters( 'use_block_editor_for_post_type', post_type_supports( $post_type, 'editor' ), $post_type );
调用
post_type_supports()
函数,判断指定的文章类型是否支持editor
特性。如果支持,则返回true
,否则返回false
。同时,使用apply_filters()
函数,允许开发者通过use_block_editor_for_post_type
过滤器来修改返回值。
五、post_type_supports()
函数
post_type_supports()
函数用于检查文章类型是否支持某个特性,例如 editor
、thumbnail
等。
<?php
/**
* Checks if a post type supports a given feature.
*
* @since 3.0.0
*
* @global array $_wp_post_type_features An array of post type features.
*
* @param string $post_type The post type to check.
* @param string|false $feature The feature to check for.
* @return bool True if the post type supports the feature, false otherwise.
*/
function post_type_supports( $post_type, $feature ) {
global $_wp_post_type_features;
if ( ! isset( $_wp_post_type_features[ $post_type ] ) ) {
return false;
}
if ( ! isset( $_wp_post_type_features[ $post_type ][ $feature ] ) ) {
return false;
}
return true;
}
这个函数依赖于全局变量 $_wp_post_type_features
,它是一个多维数组,存储了每个文章类型支持的特性。如果 $post_type
和 $feature
都存在于该数组中,则返回 true
,否则返回 false
。
六、总结:is_gutenberg_page()
的判断逻辑
现在,咱们可以总结一下 is_gutenberg_page()
的判断逻辑了:
- 首先,判断当前页面文件名 (
$pagenow
)。 - 然后,根据
$pagenow
的值,进行不同的判断:- 如果是编辑或新建文章页面 (
post.php
或post-new.php
),则调用use_block_editor_for_post_type()
函数,判断当前文章类型是否启用了 Gutenberg 编辑器。 - 如果是小工具页面 (
widgets.php
),则默认使用 Gutenberg 编辑器。 - 如果是站点编辑器页面 (
site-editor.php
),则默认使用 Gutenberg 编辑器。 - 如果是主题页面 (
themes.php
) 且 URL 中包含gutenberg-edit-site
参数,则使用 Gutenberg 编辑器。 - 如果是站点健康工具或登录页面,则禁用 Gutenberg 编辑器。
- 如果是编辑或新建文章页面 (
- 最后,通过
apply_filters()
函数,允许开发者自定义 Gutenberg 编辑器的启用逻辑。
用表格总结如下:
页面文件名 ($pagenow ) |
判断逻辑 |
---|---|
post.php , post-new.php |
调用 use_block_editor_for_post_type($current_screen->post_type) |
widgets.php |
使用 Gutenberg 编辑器 |
site-editor.php |
使用 Gutenberg 编辑器 |
themes.php |
只有当URL参数包含 gutenberg-edit-site 时,使用 Gutenberg 编辑器 |
site-health.php , wp-login.php |
不使用 Gutenberg 编辑器 |
其他 | 默认不使用 Gutenberg 编辑器,但可以通过 use_block_editor_for_post 过滤器进行修改 |
七、如何使用 is_gutenberg_page()
?
在你的插件或主题代码中,你可以像这样使用 is_gutenberg_page()
函数:
<?php
if ( is_gutenberg_page() ) {
// 当前页面正在使用 Gutenberg 编辑器
wp_enqueue_style( 'my-plugin-gutenberg-style', plugin_dir_url( __FILE__ ) . 'css/gutenberg.css' );
} else {
// 当前页面正在使用经典编辑器或其他页面
wp_enqueue_style( 'my-plugin-classic-style', plugin_dir_url( __FILE__ ) . 'css/classic.css' );
}
这段代码会根据当前页面使用的编辑器类型,加载不同的 CSS 样式。
八、利用过滤器自定义 Gutenberg 编辑器的启用逻辑
正如我们前面提到的,is_gutenberg_page()
函数使用了 use_block_editor_for_post
过滤器,允许开发者自定义 Gutenberg 编辑器的启用逻辑。
例如,你可以这样禁用所有文章类型的 Gutenberg 编辑器:
<?php
add_filter( 'use_block_editor_for_post', '__return_false' );
或者,你可以只针对特定文章类型禁用 Gutenberg 编辑器:
<?php
add_filter( 'use_block_editor_for_post_type', 'my_disable_gutenberg_for_my_post_type', 10, 2 );
function my_disable_gutenberg_for_my_post_type( $use_block_editor, $post_type ) {
if ( 'my_post_type' === $post_type ) {
return false;
}
return $use_block_editor;
}
这段代码会禁用 my_post_type
文章类型的 Gutenberg 编辑器。
九、注意事项
- 缓存: 在某些情况下,
is_gutenberg_page()
的结果可能会被缓存。如果你发现它的返回值不正确,可以尝试清除缓存。 - 主题兼容性: 某些主题可能会修改 WordPress 的默认行为,导致
is_gutenberg_page()
的返回值不准确。在开发插件或主题时,需要注意与其他主题的兼容性。 - 第三方插件: 某些第三方插件也可能会影响 Gutenberg 编辑器的启用状态。在开发插件时,需要注意与其他插件的兼容性。
十、总结
is_gutenberg_page()
是一个非常有用的函数,它可以帮助你判断当前页面是否正在使用 Gutenberg 编辑器。通过理解它的源码和使用方法,你可以更好地控制 WordPress 的编辑体验,并开发出更兼容 Gutenberg 编辑器的插件和主题。记住,灵活运用过滤器,可以让你自定义 Gutenberg 编辑器的启用逻辑,满足各种需求。
好了,今天的讲座就到这里。希望大家能从中学到一些东西。 咱们下期再见!