详解 WordPress `use_block_editor_for_post()` 函数的源码:如何判断某篇文章是否应使用 Gutenberg。

嘿,各位代码旅行者,欢迎来到今天的 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,它会尝试获取主循环中的当前文章。
  • 返回值: truefalse,分别表示启用或禁用块编辑器。

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 );
}

看起来有点长,但别慌,我们一步一步来。

  1. 获取文章对象:

    $post = get_post( $post );
    
    if ( ! $post ) {
        return false;
    }

    首先,它使用 get_post() 函数来获取文章对象。 如果传入的 $post 是文章 ID,get_post() 会把它转换成 WP_Post 对象。 如果 $postnullget_post() 会尝试获取主循环中的当前文章。 如果获取失败(比如文章不存在),直接返回 false,表示不使用块编辑器。 这就像是进入编辑器的入场券,连文章都找不到,还谈什么编辑?

  2. 获取文章类型:

    $post_type = get_post_type( $post );
    
    if ( ! post_type_exists( $post_type ) ) {
        return false;
    }

    接下来,它使用 get_post_type() 函数获取文章的类型(比如 ‘post’、’page’、’product’ 等)。 然后,它使用 post_type_exists() 函数检查这个文章类型是否存在。 如果文章类型不存在,直接返回 false。 这就像是确认文章的身份,身份不明的文章,谢绝入内。

  3. 获取文章类型对象:

    $post_type_object = get_post_type_object( $post_type );
    
    if ( ! $post_type_object ) {
        return false;
    }

    这里,它使用 get_post_type_object() 函数获取文章类型对象(WP_Post_Type)。 这个对象包含了文章类型的各种属性和设置。 如果获取失败,直接返回 false

  4. 检查 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_restfalse,那么 Gutenberg 编辑器就无法使用。 这就像是确认文章是否支持“云端同步”,不支持云端同步的,Gutenberg 用不了。

  5. 检查 editor 支持:

    if ( ! post_type_supports( $post_type, 'editor' ) ) {
        return false;
    }

    这里,它使用 post_type_supports() 函数检查文章类型是否支持 editor 特性。 editor 特性表示文章类型是否支持编辑器(可以是 Gutenberg,也可以是经典编辑器)。 如果不支持 editor,直接返回 false。 这就像是确认文章是否支持编辑功能,没有编辑功能的,那还编辑个啥?

  6. 应用过滤器:

    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;
}

这段代码做了什么?

  1. 添加过滤器: add_filter() 函数将 disable_gutenberg_for_book() 函数添加到 use_block_editor_for_post_type 过滤器中。
  2. 定义回调函数: disable_gutenberg_for_book() 函数接收两个参数:$use_block_editor(默认值为 true)和 $post_type(当前文章类型)。
  3. 检查文章类型: 函数检查 $post_type 是否等于 'book'。 如果是,它返回 false,表示禁用 Gutenberg 编辑器。
  4. 返回默认值: 如果 $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_restfalse,返回 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 开发者来说至关重要。

记住,代码的世界就像一个巨大的迷宫,只有不断探索,才能找到宝藏! 下次再见!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注