各位观众老爷们,早上好!欢迎来到今天的“WordPress源码解剖课”。今天咱们要聊的是一个在WordPress开发中经常会用到的函数:is_block_editor()
。这玩意儿就像个门卫,专门负责告诉你:嘿,哥们,现在是区块编辑器地盘儿,还是经典编辑器说了算?
废话不多说,直接上干货!
一、 is_block_editor()
的身世之谜
is_block_editor()
函数,顾名思义,就是用来判断当前页面是否正在使用区块编辑器(Gutenberg编辑器)。自从WordPress 5.0引入区块编辑器以来,它就成了区分新旧编辑器的关键。
二、 源码解剖:扒光 is_block_editor()
的衣服
要了解一个函数,最好的办法就是直接看它的源码。让我们一起潜入WordPress核心代码,找到 is_block_editor()
的真身。
(以下代码基于WordPress 6.4.2版本)
/**
* Determines whether the current page is the block editor.
*
* @since 5.0.0
*
* @global WP_Screen $current_screen WordPress screen object.
*
* @return bool True if the current page is the block editor, false otherwise.
*/
function is_block_editor() {
global $current_screen;
if ( ! is_admin() ) {
return false;
}
if ( ! function_exists( 'get_current_screen' ) ) {
return false;
}
$screen = get_current_screen();
if ( ! $screen ) {
return false;
}
// The new widgets block editor screen.
if ( 'widgets' === $screen->id && use_widgets_block_editor() ) {
return true;
}
// The new customize block editor screen.
if ( 'customize' === $screen->id && use_widgets_block_editor() ) {
return true;
}
if ( method_exists( $screen, 'is_block_editor' ) && $screen->is_block_editor() ) {
return true;
}
$post_types = get_post_types( array( 'show_in_rest' => true ) );
if ( is_array( $post_types ) && in_array( $screen->post_type, $post_types, true ) ) {
return true;
}
return false;
}
怎么样,是不是感觉有点像看天书?别怕,咱们一点点拆解。
三、 源码逐行解读:抽丝剥茧,还原真相
-
function is_block_editor() {
: 这行代码定义了函数is_block_editor()
,没有参数,返回一个布尔值(true
或false
)。 -
global $current_screen;
: 声明使用全局变量$current_screen
。这个变量包含了当前屏幕(页面)的信息,比如ID、post type等等。 -
if ( ! is_admin() ) { return false; }
: 这一行很重要。is_admin()
函数判断当前是否在后台管理界面。如果不在后台,那肯定不是区块编辑器,直接返回false
。记住,区块编辑器只在后台使用。 -
if ( ! function_exists( 'get_current_screen' ) ) { return false; }
: 检查get_current_screen()
函数是否存在。这个函数是用来获取$current_screen
对象的。如果不存在,说明WordPress环境有问题,直接返回false
。 -
$screen = get_current_screen();
: 获取$current_screen
对象,并赋值给变量$screen
。 -
if ( ! $screen ) { return false; }
: 检查$screen
对象是否为空。如果为空,说明没有获取到屏幕信息,返回false
。 -
if ( 'widgets' === $screen->id && use_widgets_block_editor() ) { return true; }
和if ( 'customize' === $screen->id && use_widgets_block_editor() ) { return true; }
: 这两行代码是针对小工具和自定义界面的区块编辑器。$screen->id
存储了当前屏幕的ID。如果ID是'widgets'
或'customize'
,并且use_widgets_block_editor()
函数返回true
,则表示当前正在使用小工具或自定义界面的区块编辑器,返回true
。use_widgets_block_editor()
函数会检查主题是否支持区块小工具。 -
if ( method_exists( $screen, 'is_block_editor' ) && $screen->is_block_editor() ) { return true; }
: 这行代码检查$screen
对象是否存在is_block_editor()
方法,如果存在并且调用该方法返回true
,则认为当前是区块编辑器。 这允许主题或插件更精细地控制区块编辑器的启用。 -
$post_types = get_post_types( array( 'show_in_rest' => true ) );
: 获取所有show_in_rest
为true
的 post types。show_in_rest
参数决定了该 post type 是否支持 REST API,而区块编辑器正是基于 REST API 构建的。 -
if ( is_array( $post_types ) && in_array( $screen->post_type, $post_types, true ) ) { return true; }
: 如果$post_types
是一个数组,并且当前屏幕的 post type ($screen->post_type
) 存在于$post_types
数组中,则认为当前是区块编辑器。in_array(..., true)
使用严格比较,确保类型和值都相同。 -
return false;
: 如果以上所有条件都不满足,则最终返回false
,表示当前不是区块编辑器。
四、 逻辑梳理:拨开云雾见青天
让我们用更简洁的语言总结一下 is_block_editor()
函数的判断逻辑:
- 首先,确认当前是否在后台管理界面。 不在后台,肯定不是区块编辑器。
- 检查WordPress环境是否正常。 如果
get_current_screen()
函数不存在,或者$current_screen
对象为空,说明环境有问题。 - 判断是否是小工具或自定义界面的区块编辑器。 通过检查
$screen->id
和use_widgets_block_editor()
函数的返回值来判断。 - 检查
$screen
对象是否存在is_block_editor()
方法,并调用该方法。 - 获取所有支持 REST API 的 post types。 如果当前屏幕的 post type 属于这些 post types,则认为是区块编辑器。
- 如果以上条件都不满足,则认为不是区块编辑器。
用表格的形式总结如下:
条件 | 返回值 | 说明 |
---|---|---|
! is_admin() |
false |
不在后台管理界面 |
! function_exists( 'get_current_screen' ) |
false |
get_current_screen() 函数不存在 |
! $screen |
false |
$current_screen 对象为空 |
'widgets' === $screen->id && use_widgets_block_editor() |
true |
小工具界面的区块编辑器 |
'customize' === $screen->id && use_widgets_block_editor() |
true |
自定义界面的区块编辑器 |
method_exists( $screen, 'is_block_editor' ) && $screen->is_block_editor() |
true |
$screen 对象存在 is_block_editor() 方法,且返回 true |
in_array( $screen->post_type, $post_types, true ) ,其中 $post_types 是 show_in_rest 为 true 的 post types 数组 |
true |
当前 post type 支持 REST API |
以上条件均不满足 | false |
不是区块编辑器 |
五、 实战演练: is_block_editor()
的应用场景
了解了 is_block_editor()
的原理,接下来看看它在实际开发中有什么用武之地。
-
加载不同的 CSS/JavaScript 文件:
在主题或插件中,你可能需要根据编辑器类型加载不同的样式或脚本。
function my_enqueue_scripts() { if ( is_block_editor() ) { wp_enqueue_style( 'my-block-editor-style', get_template_directory_uri() . '/css/block-editor.css' ); wp_enqueue_script( 'my-block-editor-script', get_template_directory_uri() . '/js/block-editor.js', array( 'wp-blocks', 'wp-element' ), '1.0', true ); } else { wp_enqueue_style( 'my-classic-editor-style', get_template_directory_uri() . '/css/classic-editor.css' ); wp_enqueue_script( 'my-classic-editor-script', get_template_directory_uri() . '/js/classic-editor.js', array( 'jquery' ), '1.0', true ); } } add_action( 'admin_enqueue_scripts', 'my_enqueue_scripts' );
-
执行不同的操作:
有时候,你需要在区块编辑器和经典编辑器中执行不同的操作。
function my_admin_notice() { if ( is_block_editor() ) { echo '<div class="notice notice-info is-dismissible"><p>欢迎使用区块编辑器!</p></div>'; } else { echo '<div class="notice notice-info is-dismissible"><p>欢迎使用经典编辑器!</p></div>'; } } add_action( 'admin_notices', 'my_admin_notice' );
-
控制 metabox 的显示:
如果你的 metabox 与区块编辑器不兼容,可以只在经典编辑器中显示。
function my_add_metabox() { if ( ! is_block_editor() ) { add_meta_box( 'my_metabox', '我的 Metabox', 'my_metabox_callback', 'post', 'normal', 'default' ); } } add_action( 'add_meta_boxes', 'my_add_metabox' );
-
与
use_block_editor_for_post()
配合使用:use_block_editor_for_post()
函数用于判断特定 post type 是否使用区块编辑器。它可以与is_block_editor()
结合使用,实现更精确的控制。function my_custom_editor_check( $use_block_editor, $post ) { // 只有 'product' 类型的 post 才使用区块编辑器 if ( $post->post_type === 'product' ) { return true; } else { return false; } } add_filter( 'use_block_editor_for_post', 'my_custom_editor_check', 10, 2 ); function my_conditional_action() { global $post; if ( is_block_editor() && $post && $post->post_type === 'product' ) { // 只在 product 类型的 post 的区块编辑器中执行 echo '<script>console.log("Product Block Editor");</script>'; } } add_action( 'admin_enqueue_scripts', 'my_conditional_action' );
六、 注意事项:避免踩坑
- 不要在前端使用
is_block_editor()
:is_block_editor()
函数只在后台管理界面有效。在前端使用它可能会导致不可预测的结果。 - 注意缓存问题: 如果你的网站使用了缓存插件,可能会导致
is_block_editor()
的返回值不正确。建议在必要时清理缓存。 - 主题兼容性: 有些主题可能对区块编辑器的支持不够完善,导致
is_block_editor()
的行为异常。
七、 总结:学以致用,融会贯通
今天,我们深入剖析了 is_block_editor()
函数的源码,了解了它的判断逻辑和应用场景。希望通过今天的学习,大家能够更加熟练地运用 is_block_editor()
函数,在WordPress开发中如鱼得水。
记住,理解源码不是目的,目的是更好地解决实际问题。希望大家能够把今天学到的知识应用到自己的项目中,创造出更优秀的作品。
今天的讲座就到这里,感谢大家的收听!下次有机会再和大家一起解剖其他的WordPress源码。祝大家编码愉快!