WordPress 中的区块通常打包在插件中,并使用 block.json 元数据在服务器端和客户端进行注册。
虽然可以在客户端单独注册区块,但最佳实践强烈建议在服务器端和客户端都进行注册。这种双重注册对于启用动态渲染、区块支持、区块钩子和样式变体等服务器端功能至关重要。如果没有服务器端注册,这些功能将无法正常工作。
例如,如果您希望一个区块 通过 theme.json 进行样式设置,则必须在服务器端对其进行注册。否则,该区块将无法识别或应用 theme.json 中为其分配的样式。
下图详细介绍了区块的注册过程。
使用 PHP 注册区块(服务器端)
服务器端的区块注册发生在主插件 PHP 文件中,钩挂在 init。WordPress 为此提供了几个函数,具体取决于您的需求以及您针对的最低 WordPress 版本。
使用元数据集合一次性注册所有区块(推荐)
自 WordPress 6.8 以来,注册区块的推荐方法是 wp_register_block_types_from_metadata_collection()。此函数在一个调用中注册 blocks-manifest.php 文件中定义的所有区块类型,从而消除了对单独的 register_block_type() 调用的需求。
blocks-manifest.php 文件由 wp-scripts build-blocks-manifest 命令自动生成(或者通过向 build 和 start 命令传递 --blocks-manifest 标志)。它将项目中所有 block.json 文件中的元数据编译到一个 PHP 文件中。
function my_plugin_register_blocks() {
wp_register_block_types_from_metadata_collection(
__DIR__ . '/build',
__DIR__ . '/build/blocks-manifest.php'
);
}
add_action( 'init', 'my_plugin_register_blocks' );
这是 create-block 脚手架工具所使用的方法。它通过避免从磁盘读取多个 block.json 文件来提高性能,并简化了插件的注册代码——特别是对于具有多个区块的插件。
wp_register_block_types_from_metadata_collection() 需要 WordPress 6.8 或更高版本。有关更多详细信息,请参阅 WordPress 6.8 开发说明。单独注册元数据集合(WordPress 6.7+)
如果您需要更精确地控制单个区块的注册方式(例如,为每个区块传递不同的 $args),您可以使用 wp_register_block_metadata_collection() 先注册清单,然后对每个区块单独调用 register_block_type()。WordPress 将从已加载的清单中读取每个区块的元数据,而不是从磁盘读取。
function my_plugin_register_blocks() {
wp_register_block_metadata_collection(
__DIR__ . '/build',
__DIR__ . '/build/blocks-manifest.php'
);
register_block_type( __DIR__ . '/build/block-one' );
register_block_type( __DIR__ . '/build/block-two', array(
'render_callback' => 'my_plugin_render_block_two',
) );
}
add_action( 'init', 'my_plugin_register_blocks' );
wp_register_block_metadata_collection() 需要 WordPress 6.7 或更高版本。有关更多详细信息,请参阅 WordPress 6.7 开发说明。使用 register_block_type() 注册单个区块
register_block_type() 函数通过从 block.json 文件读取元数据来注册单个区块类型。这仍然是一种有效的方法,特别是对于只有一个区块的插件或针对低于 6.7 版本的 WordPress 时。
此函数主要使用两个参数:
$block_type(string): 包含block.json文件的目录路径,或者如果文件名不同则为元数据文件的完整路径。$args(array): 用于区块类型的额外参数的可选数组。这可以包括render_callback作为block.json中render属性的替代方案。
在开发过程中,block.json 文件通常从 src(源)目录移动到 build 目录,作为编译代码的一部分。因此,在注册区块时,请确保 $block_type 路径指向 build 目录中的 block.json 文件。
register_block_type() 函数在成功时返回注册的区块类型 (WP_Block_Type),或在失败时返回 false。以下是使用 render_callback 的简单示例。
register_block_type(
__DIR__ . '/build',
array(
'render_callback' => 'render_block_core_notice',
)
);
这是一个更完整的示例,包括 init 钩子。
function minimal_block_ca6eda___register_block() {
register_block_type( __DIR__ . '/build' );
}
add_action( 'init', 'minimal_block_ca6eda___register_block' );
具有自动注册的纯 PHP 区块
对于只需要服务器端渲染的区块,您可以使用 autoRegister 标志和 render_callback 在 PHP 中专门注册它们。这些区块会自动出现在编辑器中,无需任何 JavaScript 注册或客户端代码,并使用 动态渲染。
register_block_type( 'my-plugin/server-block', array(
'render_callback' => function( $attributes ) {
$wrapper_attributes = get_block_wrapper_attributes();
return sprintf(
'<div %1$s>Server content</div>',
$wrapper_attributes
);
},
'supports' => array(
'autoRegister' => true,
'color' => array(
'background' => true,
),
),
) );
使用 JavaScript 注册区块(客户端)
当区块已在服务器端注册,并且不使用 纯 PHP 自动注册区块 时,您只需使用 @wordpress/blocks 包中的 registerBlockType 方法在 JavaScript 中注册客户端设置。您只需确保使用与区块的 block.json 文件中定义的相同的区块名称即可。示例如下:
import { registerBlockType } from '@wordpress/blocks';
registerBlockType( 'my-plugin/notice', {
edit: Edit,
// ...其他客户端设置
} );
虽然通常建议使用 PHP 在服务器端注册区块以获得 “使用元数据文件的优点” 部分中概述的好处,但您可以选择仅在客户端注册区块。registerBlockType 方法允许您使用元数据注册区块类型。
该函数接受两个参数:
blockNameOrMetadata(string|Object): 这可以是区块类型的名称(字符串)或包含区块元数据的对象,通常从block.json文件加载。settings(Object): 这是包含区块客户端设置的对象。
wp-scripts 提供的那个)直接将 block.json 文件(或任何其他 .json 文件)的内容导入到您的 JavaScript 文件中。作为第二个参数传递的 settings 对象包含许多属性,但以下两个最为重要:
edit: 在编辑器中用于我们块的 React 组件。save: 返回保存至数据库的静态 HTML 标记的函数。
registerBlockType() 函数在成功时返回已注册的块类型 (WPBlock),或在失败时返回 undefined。示例如下:
import { registerBlockType } from '@wordpress/blocks';
import { useBlockProps } from '@wordpress/block-editor';
import metadata from './block.json';
const Edit = () => <p { ...useBlockProps() }>Hello World - Block Editor</p>;
const save = () => <p { ...useBlockProps.save() }>Hello World - Frontend</p>;
registerBlockType( metadata.name, {
edit: Edit,
save,
} );
其他资源
wp_register_block_types_from_metadata_collectionPHP 函数 (WordPress 6.8+)wp_register_block_metadata_collectionPHP 函数 (WordPress 6.7+)register_block_typePHP 函数registerBlockTypeJS 函数- 6.8 中更高效的块类型注册 | WordPress Core 开发笔记
- 6.7 中的新块类型注册 API 以提升性能 | WordPress Core 开发笔记
- 为什么块需要在服务器和客户端都进行注册? | GitHub 讨论
- 块注册图表
