嘿,各位代码旅行者,欢迎来到今天的 Gutenberg 探险课堂! 今天我们要扒一扒 WordPress 中一个相当关键的函数:use_block_editor_for_post()
。 它的作用嘛,简单来说,就是判断一篇文章(Post)应该用 Gutenberg 编辑器(也就是块编辑器)还是传统的经典编辑器。 别看它名字平平无奇,实际上它背后藏着不少门道。 准备好,我们这就开始深入挖掘!
第一站:use_block_editor_for_post()
的表面功夫
首先,让我们看看这个函数的官方文档(虽然有时候官方文档就像藏宝图,指了个大概方向,剩下的得自己摸索)。
/**
* Determines whether the block editor is enabled for the given post.
*
* @since 5.0.0
*
* @param WP_Post|int|null $post Optional. Post to check. Defaults to the current post in the main loop.
* @return bool True if the block editor is enabled, false otherwise.
*/
function use_block_editor_for_post( $post = null ) {
// ... 核心逻辑在这里 ...
}
从文档里,我们可以提取出几个关键信息:
- 作用: 确定给定的文章是否启用了块编辑器。
- 参数:
$post
,可选参数,可以传入一个WP_Post
对象、文章 ID,或者null
。 如果是null
,它会尝试获取主循环中的当前文章。 - 返回值:
true
或false
,分别表示启用或禁用块编辑器。
OK,表面功夫到此为止。接下来,我们要深入到函数的内部,看看它到底是怎么工作的。
第二站:深入 use_block_editor_for_post()
的源码
是时候打开你的代码编辑器,跟随我一起穿越到 WordPress 的核心文件了。 这个函数通常位于 wp-includes/functions.php
文件中。 让我们一起庖丁解牛,看看它的真面目。
function use_block_editor_for_post( $post = null ) {
$post = get_post( $post );
if ( ! $post ) {
return false;
}
$post_type = get_post_type( $post );
if ( ! post_type_exists( $post_type ) ) {
return false;
}
$post_type_object = get_post_type_object( $post_type );
if ( ! $post_type_object ) {
return false;
}
if ( ! isset( $post_type_object->show_in_rest ) || ! $post_type_object->show_in_rest ) {
return false;
}
if ( ! post_type_supports( $post_type, 'editor' ) ) {
return false;
}
/**
* Filters whether the block editor should be used for the given post type.
*
* @since 5.0.0
*
* @param bool $use_block_editor Whether to use the block editor.
* @param string $post_type The post type being checked.
* @param WP_Post $post The post being checked.
*/
return apply_filters( 'use_block_editor_for_post_type', true, $post_type, $post );
}
看起来有点长,但别慌,我们一步一步来。
-
获取文章对象:
$post = get_post( $post ); if ( ! $post ) { return false; }
首先,它使用
get_post()
函数来获取文章对象。 如果传入的$post
是文章 ID,get_post()
会把它转换成WP_Post
对象。 如果$post
是null
,get_post()
会尝试获取主循环中的当前文章。 如果获取失败(比如文章不存在),直接返回false
,表示不使用块编辑器。 这就像是进入编辑器的入场券,连文章都找不到,还谈什么编辑? -
获取文章类型:
$post_type = get_post_type( $post ); if ( ! post_type_exists( $post_type ) ) { return false; }
接下来,它使用
get_post_type()
函数获取文章的类型(比如 ‘post’、’page’、’product’ 等)。 然后,它使用post_type_exists()
函数检查这个文章类型是否存在。 如果文章类型不存在,直接返回false
。 这就像是确认文章的身份,身份不明的文章,谢绝入内。 -
获取文章类型对象:
$post_type_object = get_post_type_object( $post_type ); if ( ! $post_type_object ) { return false; }
这里,它使用
get_post_type_object()
函数获取文章类型对象(WP_Post_Type
)。 这个对象包含了文章类型的各种属性和设置。 如果获取失败,直接返回false
。 -
检查
show_in_rest
属性:if ( ! isset( $post_type_object->show_in_rest ) || ! $post_type_object->show_in_rest ) { return false; }
这是个关键的判断。
show_in_rest
属性决定了文章类型是否应该在 REST API 中显示。 Gutenberg 编辑器严重依赖 REST API,所以如果show_in_rest
为false
,那么 Gutenberg 编辑器就无法使用。 这就像是确认文章是否支持“云端同步”,不支持云端同步的,Gutenberg 用不了。 -
检查
editor
支持:if ( ! post_type_supports( $post_type, 'editor' ) ) { return false; }
这里,它使用
post_type_supports()
函数检查文章类型是否支持editor
特性。editor
特性表示文章类型是否支持编辑器(可以是 Gutenberg,也可以是经典编辑器)。 如果不支持editor
,直接返回false
。 这就像是确认文章是否支持编辑功能,没有编辑功能的,那还编辑个啥? -
应用过滤器:
return apply_filters( 'use_block_editor_for_post_type', true, $post_type, $post );
最后,它应用了一个名为
use_block_editor_for_post_type
的过滤器。 这个过滤器允许开发者通过编写插件或主题代码,来修改 Gutenberg 编辑器的启用/禁用状态。 默认情况下,这个过滤器返回true
,表示启用 Gutenberg 编辑器。 这就像是给开发者留了一个后门,允许他们根据自己的需求来定制 Gutenberg 编辑器的行为。
第三站:show_in_rest
的重要性
刚才我们提到了 show_in_rest
属性,这个属性对于 Gutenberg 编辑器来说至关重要。 让我们来深入了解一下它。
show_in_rest
属性是在注册文章类型时定义的,例如:
function my_custom_post_type() {
$args = array(
'public' => true,
'label' => 'My Custom Posts',
'supports' => array( 'title', 'editor', 'thumbnail' ),
'show_in_rest' => true, // 关键在这里!
);
register_post_type( 'my_custom_post', $args );
}
add_action( 'init', 'my_custom_post_type' );
如果 show_in_rest
设置为 true
,那么这个文章类型就可以在 REST API 中使用。 Gutenberg 编辑器会通过 REST API 来获取和保存文章的内容。
如果 show_in_rest
设置为 false
,那么 Gutenberg 编辑器就无法使用,WordPress 会自动回退到经典编辑器。
第四站:实战演练:禁用特定文章类型的 Gutenberg 编辑器
现在,让我们通过一个实际的例子来演示如何使用 use_block_editor_for_post_type
过滤器来禁用特定文章类型的 Gutenberg 编辑器。
假设我们有一个名为 book
的自定义文章类型,我们想要禁用它的 Gutenberg 编辑器。 我们可以这样做:
add_filter( 'use_block_editor_for_post_type', 'disable_gutenberg_for_book', 10, 2 );
function disable_gutenberg_for_book( $use_block_editor, $post_type ) {
if ( $post_type === 'book' ) {
return false;
}
return $use_block_editor;
}
这段代码做了什么?
- 添加过滤器:
add_filter()
函数将disable_gutenberg_for_book()
函数添加到use_block_editor_for_post_type
过滤器中。 - 定义回调函数:
disable_gutenberg_for_book()
函数接收两个参数:$use_block_editor
(默认值为true
)和$post_type
(当前文章类型)。 - 检查文章类型: 函数检查
$post_type
是否等于'book'
。 如果是,它返回false
,表示禁用 Gutenberg 编辑器。 - 返回默认值: 如果
$post_type
不是'book'
,它返回$use_block_editor
,保持默认的启用状态。
这样,当编辑 book
类型的文章时,WordPress 就会自动使用经典编辑器。
第五站:代码表格:use_block_editor_for_post()
流程总结
为了更好地理解 use_block_editor_for_post()
函数的工作流程,我们可以用一个表格来总结一下:
步骤 | 代码 | 描述 | 返回值 |
---|---|---|---|
1 | $post = get_post( $post ); |
获取文章对象。 | 如果文章不存在,返回 false 。 |
2 | $post_type = get_post_type( $post ); |
获取文章类型。 | 如果文章类型不存在,返回 false 。 |
3 | $post_type_object = get_post_type_object( $post_type ); |
获取文章类型对象。 | 如果文章类型对象不存在,返回 false 。 |
4 | if ( ! isset( $post_type_object->show_in_rest ) || ! $post_type_object->show_in_rest ) |
检查 show_in_rest 属性。 |
如果 show_in_rest 为 false ,返回 false 。 |
5 | if ( ! post_type_supports( $post_type, 'editor' ) ) |
检查 editor 特性支持。 |
如果不支持 editor ,返回 false 。 |
6 | return apply_filters( 'use_block_editor_for_post_type', true, $post_type, $post ); |
应用过滤器。 | 返回过滤器修改后的值(默认为 true )。 |
第六站:常见问题解答
-
问:为什么我的自定义文章类型无法使用 Gutenberg 编辑器?
答:很有可能是
show_in_rest
属性没有设置为true
。 请检查你的文章类型注册代码,确保show_in_rest
设置为true
。 另外,确认文章类型是否支持editor
特性。 -
问:我可以使用
use_block_editor_for_post_type
过滤器来强制启用 Gutenberg 编辑器吗?答:可以。 你可以将过滤器回调函数设置为始终返回
true
。 但是,请注意,这可能会导致一些兼容性问题,因为某些插件或主题可能不兼容 Gutenberg 编辑器。 -
问:
use_block_editor_for_post()
函数只适用于文章吗?答:理论上,它主要用于文章(Post)。 但是,由于 WordPress 的灵活性,你也可以将它用于其他类型的对象,只要这些对象可以被当作“文章”来处理。
第七站:总结与思考
好了,各位代码旅行者,今天的 Gutenberg 探险就到此为止了。 我们深入剖析了 use_block_editor_for_post()
函数的源码,了解了它的工作原理,以及如何使用它来控制 Gutenberg 编辑器的启用/禁用状态。
通过今天的学习,我们不仅了解了一个具体的 WordPress 函数,更重要的是,我们学会了如何深入阅读和理解 WordPress 的源码。 这对于成为一名优秀的 WordPress 开发者来说至关重要。
记住,代码的世界就像一个巨大的迷宫,只有不断探索,才能找到宝藏! 下次再见!