解析 WordPress `WP_Block_Pattern_Registry` 类的源码:如何管理所有注册的区块模式。

各位观众,晚上好!我是你们的老朋友,今天咱们来聊聊WordPress里一个有点神秘,但又无比重要的家伙:WP_Block_Pattern_Registry。说它神秘,是因为很多小伙伴可能平时写主题或者插件,很少直接跟它打交道。但说它重要,是因为它默默地管理着WordPress里的所有区块模式,直接影响着我们使用古腾堡编辑器时的体验。

今天这场“讲座”,咱们就来扒一扒 WP_Block_Pattern_Registry 的底裤,看看它到底是怎么管理这些区块模式的。放心,我尽量用大白话,加上一些代码示例,保证让你听得懂,记得住,还能用得上!

开场白:区块模式是啥玩意儿?

在深入 WP_Block_Pattern_Registry 之前,咱们先来回顾一下区块模式。简单来说,区块模式就是一组预先配置好的区块的集合,你可以一键插入到你的文章或者页面中。想象一下,你需要一个包含标题、图片和一段文字的区块组合,如果每次都手动添加、配置,那得多麻烦?有了区块模式,你只需要点一下,这个组合就直接出现在你的编辑器里了,简直不要太方便!

WP_Block_Pattern_Registry:区块模式的“户籍管理处”

好了,有了区块模式的概念,咱们就可以进入正题了。WP_Block_Pattern_Registry 类,顾名思义,就是一个注册表,专门用来管理WordPress中注册的所有区块模式。你可以把它想象成一个“户籍管理处”,每个区块模式都要在这里登记,才能被WordPress识别和使用。

WP_Block_Pattern_Registry 类的主要方法

WP_Block_Pattern_Registry 类主要有以下几个核心方法:

  • register( string $pattern_name, array $pattern_properties ): bool:注册一个新的区块模式。
  • unregister( string $pattern_name ): bool:注销一个已注册的区块模式。
  • is_registered( string $pattern_name ): bool:检查一个区块模式是否已经注册。
  • get_all_registered(): 获取所有已注册的区块模式。
  • get_registered( string $pattern_name ): 获取指定名称的区块模式.

接下来,咱们就逐个分析这些方法,看看它们都是怎么工作的。

1. register():给区块模式上户口

register() 方法是 WP_Block_Pattern_Registry 类最重要的一个方法,它的作用是将一个新的区块模式注册到WordPress中。它的原型如下:

public function register( string $pattern_name, array $pattern_properties ): bool {
    // 校验参数
    if ( ! is_string( $pattern_name ) ) {
        _doing_it_wrong(
            __METHOD__,
            esc_html__( 'Pattern name must be a string.', 'default' ),
            '5.5.0'
        );
        return false;
    }

    if ( ! preg_match( '/^[a-z0-9-]+(/[a-z0-9-]+)?$/', $pattern_name ) ) {
        _doing_it_wrong(
            __METHOD__,
            esc_html__( 'Pattern name must contain only lowercase alphanumeric characters, dashes, and optionally one forward slash.', 'default' ),
            '5.5.0'
        );
        return false;
    }

    if ( $this->is_registered( $pattern_name ) ) {
        return false;
    }

    if ( ! is_array( $pattern_properties ) ) {
        _doing_it_wrong(
            __METHOD__,
            esc_html__( 'Pattern properties must be an array.', 'default' ),
            '5.5.0'
        );
        return false;
    }

    if ( ! isset( $pattern_properties['title'] ) || ! is_string( $pattern_properties['title'] ) ) {
        _doing_it_wrong(
            __METHOD__,
            esc_html__( 'Pattern properties must contain a title.', 'default' ),
            'default'
        );
        return false;
    }

    if ( ! isset( $pattern_properties['content'] ) || ! is_string( $pattern_properties['content'] ) ) {
        _doing_it_wrong(
            __METHOD__,
            esc_html__( 'Pattern properties must contain content.', 'default' ),
            'default'
        );
        return false;
    }

    // 过滤pattern_properties
    $pattern_properties = wp_parse_args(
        $pattern_properties,
        array(
            'categories' => array(),
            'description' => '',
            'keywords'    => array(),
            'viewportWidth' => null,
        )
    );

    $this->registered_patterns[ $pattern_name ] = $pattern_properties;

    return true;
}

这个方法接收两个参数:

  • $pattern_name:区块模式的名称,必须是字符串,并且只能包含小写字母、数字和短横线。
  • $pattern_properties:一个数组,包含区块模式的各种属性,比如标题、内容、分类等等。

简单来说,register() 方法的工作流程如下:

  1. 参数校验:检查 $pattern_name$pattern_properties 是否符合规范,比如名称是否是字符串,是否已经注册,属性是否是数组等等。如果不符合规范,会触发一个 _doing_it_wrong 错误提示,并返回 false
  2. 属性填充 如果用户没有提供默认的属性,比如categoriesdescriptionkeywordsviewportWidth,那么使用默认值填充
  3. 注册区块模式:将 $pattern_properties 存储到 $this->registered_patterns 数组中,这个数组就是用来存储所有已注册的区块模式的。

举个例子,假设我们要注册一个名为 my-custom-pattern 的区块模式,包含一个标题和一个段落,我们可以这样写:

add_action( 'init', 'register_my_custom_pattern' );

function register_my_custom_pattern() {
    register_block_pattern(
        'my-custom-pattern',
        array(
            'title'       => __( 'My Custom Pattern', 'textdomain' ),
            'categories'  => array( 'text' ),
            'description' => __( 'A simple pattern with a title and a paragraph.', 'textdomain' ),
            'content'     => '<!-- wp:heading --><h2>My Custom Title</h2><!-- /wp:heading --><!-- wp:paragraph --><p>This is my custom paragraph.</p><!-- /wp:paragraph -->',
        )
    );
}

在这个例子中,我们使用了 register_block_pattern() 函数来注册区块模式,这个函数实际上就是调用了 WP_Block_Pattern_Registry 类的 register() 方法。

表格:$pattern_properties 数组的常用属性

属性名 类型 描述
title string 区块模式的标题,会在编辑器中显示。
content string 区块模式的内容,必须是有效的区块HTML代码。
categories array 区块模式所属的分类,用于在编辑器中筛选区块模式。
description string 区块模式的描述,用于在编辑器中提供更详细的信息。
keywords array 区块模式的关键词,用于在编辑器中搜索区块模式。
viewportWidth int 模式的视口宽度,用于在模式预览中设置正确的视口宽度。

2. unregister():给区块模式销户

unregister() 方法的作用是注销一个已经注册的区块模式,它的原型如下:

public function unregister( string $pattern_name ): bool {
    if ( ! is_string( $pattern_name ) ) {
        _doing_it_wrong(
            __METHOD__,
            esc_html__( 'Pattern name must be a string.', 'default' ),
            '5.5.0'
        );
        return false;
    }

    if ( ! $this->is_registered( $pattern_name ) ) {
        return false;
    }

    unset( $this->registered_patterns[ $pattern_name ] );

    return true;
}

这个方法接收一个参数:

  • $pattern_name:要注销的区块模式的名称。

简单来说,unregister() 方法的工作流程如下:

  1. 参数校验:检查 $pattern_name 是否是字符串,以及该区块模式是否已经注册。如果不符合规范,会触发一个 _doing_it_wrong 错误提示,并返回 false
  2. 注销区块模式:从 $this->registered_patterns 数组中移除该区块模式。

举个例子,假设我们要注销之前注册的 my-custom-pattern 区块模式,我们可以这样写:

add_action( 'init', 'unregister_my_custom_pattern' );

function unregister_my_custom_pattern() {
    unregister_block_pattern( 'my-custom-pattern' );
}

在这个例子中,我们使用了 unregister_block_pattern() 函数来注销区块模式,这个函数实际上就是调用了 WP_Block_Pattern_Registry 类的 unregister() 方法。

3. is_registered():查查区块模式的户口状态

is_registered() 方法的作用是检查一个区块模式是否已经注册,它的原型如下:

public function is_registered( string $pattern_name ): bool {
    if ( ! is_string( $pattern_name ) ) {
        _doing_it_wrong(
            __METHOD__,
            esc_html__( 'Pattern name must be a string.', 'default' ),
            '5.5.0'
        );
        return false;
    }

    return isset( $this->registered_patterns[ $pattern_name ] );
}

这个方法接收一个参数:

  • $pattern_name:要检查的区块模式的名称。

简单来说,is_registered() 方法的工作流程如下:

  1. 参数校验:检查 $pattern_name 是否是字符串。如果不符合规范,会触发一个 _doing_it_wrong 错误提示,并返回 false
  2. 检查区块模式是否存在:检查 $this->registered_patterns 数组中是否存在该区块模式。如果存在,返回 true,否则返回 false

举个例子,假设我们要检查 my-custom-pattern 区块模式是否已经注册,我们可以这样写:

$is_registered = WP_Block_Pattern_Registry::get_instance()->is_registered( 'my-custom-pattern' );

if ( $is_registered ) {
    echo 'The pattern is registered!';
} else {
    echo 'The pattern is not registered!';
}

4. get_all_registered():获取所有户口信息

get_all_registered() 方法的作用是获取所有已经注册的区块模式,它的原型如下:

public function get_all_registered() {
    return $this->registered_patterns;
}

这个方法不接收任何参数,它直接返回 $this->registered_patterns 数组,这个数组包含了所有已注册的区块模式的信息。

举个例子,假设我们要获取所有已注册的区块模式,我们可以这样写:

$registered_patterns = WP_Block_Pattern_Registry::get_instance()->get_all_registered();

foreach ( $registered_patterns as $pattern_name => $pattern_properties ) {
    echo 'Pattern Name: ' . esc_html( $pattern_name ) . '<br>';
    echo 'Pattern Title: ' . esc_html( $pattern_properties['title'] ) . '<br>';
    // ... 输出其他属性
}

5. get_registered():获取指定区块模式的户口信息

get_registered() 方法的作用是获取指定名称的区块模式的信息,它的原型如下:

public function get_registered( string $pattern_name ) {
    if ( ! $this->is_registered( $pattern_name ) ) {
        return null;
    }

    return $this->registered_patterns[ $pattern_name ];
}

这个方法接收一个参数:

  • $pattern_name:要获取信息的区块模式的名称。

简单来说,get_registered() 方法的工作流程如下:

  1. 检查区块模式是否存在:首先调用 is_registered() 方法检查该区块模式是否已经注册。如果没有注册,直接返回 null
  2. 获取区块模式信息:如果已经注册,从 $this->registered_patterns 数组中获取该区块模式的信息,并返回。

举个例子,假设我们要获取 my-custom-pattern 区块模式的信息,我们可以这样写:

$pattern_properties = WP_Block_Pattern_Registry::get_instance()->get_registered( 'my-custom-pattern' );

if ( $pattern_properties ) {
    echo 'Pattern Title: ' . esc_html( $pattern_properties['title'] ) . '<br>';
    echo 'Pattern Content: ' . esc_html( $pattern_properties['content'] ) . '<br>';
    // ... 输出其他属性
} else {
    echo 'Pattern not found!';
}

WP_Block_Pattern_Registry 的单例模式

细心的朋友可能已经发现了,在上面的例子中,我们都是通过 WP_Block_Pattern_Registry::get_instance() 来获取 WP_Block_Pattern_Registry 类的实例的。这是因为 WP_Block_Pattern_Registry 类使用了单例模式。

单例模式是一种设计模式,它的目的是确保一个类只有一个实例,并提供一个全局访问点。在WordPress中,使用单例模式可以避免重复创建 WP_Block_Pattern_Registry 类的实例,从而提高性能。

WP_Block_Pattern_Registry 类的 get_instance() 方法的代码如下:

/**
 * Returns the instance.
 *
 * @return WP_Block_Pattern_Registry Returns the instance.
 */
public static function get_instance() {
    if ( is_null( self::$instance ) ) {
        self::$instance = new self();
    }

    return self::$instance;
}

这段代码很简单,就是先检查 $instance 静态变量是否为空,如果为空,就创建一个新的 WP_Block_Pattern_Registry 类的实例,并将其赋值给 $instance 静态变量。然后,返回 $instance 静态变量。

总结:WP_Block_Pattern_Registry 的重要性

WP_Block_Pattern_Registry 类是WordPress中管理区块模式的核心类,它负责注册、注销、检查和获取区块模式的信息。通过了解 WP_Block_Pattern_Registry 类的工作原理,我们可以更好地使用和扩展WordPress的区块模式功能,从而提高我们的开发效率。

希望今天的“讲座”能让你对 WP_Block_Pattern_Registry 类有更深入的了解。下次再遇到区块模式的问题,你就可以自信地说:“哼,这玩意儿我熟!”

谢谢大家!

发表回复

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