gutenbergdocs/getting-started/fundamentals/registration-of-a-block.md

122 lines
6.9 KiB
Markdown
Raw Normal View History

2025-10-21 17:33:45 +00:00
# 区块注册
WordPress中的区块通常以插件形式打包并通过`block.json`元数据在服务端和客户端进行注册。
虽然可以仅在客户端注册区块,但最佳实践强烈建议在服务端和客户端同时注册。这种双重注册对于启用服务端功能至关重要,例如动态渲染、区块支持、区块钩子和样式变体。若缺少服务端注册,这些功能将无法正常运行。
例如,若希望区块[通过`theme.json`设置样式](https://developer.wordpress.org/themes/global-settings-and-styles/settings/blocks/),则必须在服务端进行注册。否则,该区块将无法识别或应用在`theme.json`中为其分配的任何样式。
以下流程图详细说明了区块的注册过程。
[![打开区块注册流程图](https://developer.wordpress.org/files/2023/11/block-registration-e1700493399839.png)](https://developer.wordpress.org/files/2023/11/block-registration-e1700493399839.png "打开区块注册流程图")
## 使用PHP注册区块服务端
区块在服务端的注册通常发生在主插件PHP文件中通过[`init`](https://developer.wordpress.org/reference/hooks/init/)钩子调用[`register_block_type()`](https://developer.wordpress.org/reference/functions/register_block_type/)函数。该函数通过读取`block.json`文件中存储的元数据来简化区块类型注册。
此函数专为注册区块类型而设计,在此上下文中主要使用两个参数(虽然可支持更多变体):
- **`$block_type`(字符串):** 可以是包含`block.json`文件的目录路径或元数据文件的完整路径如果文件名不同。此参数告知WordPress在哪里查找区块配置。
- **`$args`(数组):** 这是一个可选参数,可用于指定区块类型的其他参数。默认情况下为空数组,但可以包含各种选项,其中之一是`$render_callback`。此回调用于在前端渲染区块,是`block.json`中`render`属性的替代方案。
在开发过程中,`block.json`文件通常作为代码编译的一部分从`src`(源)目录移动到`build`目录。因此,在注册区块时,请确保`$block_type`路径指向`build`目录中的`block.json`文件。
`register_block_type()`函数在成功时返回注册的区块类型(`WP_Block_Type`),失败时返回`false`。以下是一个使用`render_callback`的简单示例。
```php
register_block_type(
__DIR__ . '/build',
array(
'render_callback' => 'render_block_core_notice',
)
);
```
以下是一个更完整的示例,包括`init`钩子。
```php
function minimal_block_ca6eda___register_block() {
register_block_type( __DIR__ . '/build' );
}
add_action( 'init', 'minimal_block_ca6eda___register_block' );
```
_查看[上述代码](https://github.com/WordPress/block-development-examples/blob/trunk/plugins/minimal-block-ca6eda/plugin.php)的[完整区块示例](https://github.com/WordPress/block-development-examples/tree/trunk/plugins/minimal-block-ca6eda)_
### 仅限PHP的自动注册区块
对于仅需服务端渲染的区块,您可以使用[`auto_register`](/docs/reference-guides/block-api/block-supports.md#auto_register)标志和`render_callback`在PHP中单独注册。这些区块会自动出现在编辑器中无需任何JavaScript注册或客户端代码并使用[动态渲染](/docs/getting-started/fundamentals/static-dynamic-rendering.md)。
```php
register_block_type( 'my-plugin/server-block', array(
'render_callback' => function( $attributes ) {
$wrapper_attributes = get_block_wrapper_attributes();
return sprintf(
'<div %1$s>服务器内容</div>',
$wrapper_attributes
);
},
'supports' => array(
'auto_register' => true,
'color' => array(
'background' => true,
),
),
) );
```
## 使用JavaScript注册区块客户端
当区块已在服务端注册且未使用[仅限PHP的自动注册区块](#仅限php的自动注册区块)时,您只需使用`@wordpress/blocks`包中的[`registerBlockType`](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-blocks/#registerblocktype)方法在JavaScript中注册客户端设置。只需确保使用与区块`block.json`文件中定义的相同区块名称。以下是一个示例:
```js
import { registerBlockType } from '@wordpress/blocks';
registerBlockType( 'my-plugin/notice', {
edit: Edit,
// ...其他客户端设置
} );
```
虽然通常建议使用PHP在服务端注册区块以获得["使用元数据文件的好处"](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/#benefits-using-the-metadata-file)部分所述的优势,但您也可以选择仅在客户端注册区块。`registerBlockType`方法允许您使用元数据注册区块类型。
该函数接受两个参数:
- **`blockNameOrMetadata`(字符串|对象):** 可以是区块类型的名称(字符串),也可以是包含区块元数据的对象(通常从`block.json`文件加载)。
- **`settings`(对象):** 这是一个包含区块客户端设置的对象。
<div class="callout callout-tip">
如果您使用构建过程(例如<a href="https://developer.wordpress.org/block-editor/getting-started/devenv/get-started-with-wp-scripts/#the-build-process-with-wp-scripts"><code>wp-scripts</code></a>提供的构建过程),可以直接将<code>block.json</code>文件(或任何其他<code>.json</code>文件的内容导入到JavaScript文件中。
</div>
作为第二个参数传递的`settings`对象包含许多属性,但以下两个是最重要的:
- **`edit`** 在编辑器中用于我们区块的React组件。
- **`save`** 返回保存到数据库的静态HTML标记的函数。
`registerBlockType()`函数在成功时返回注册的区块类型(`WPBlock`),失败时返回`undefined`。以下是一个示例:
```js
import { registerBlockType } from '@wordpress/blocks';
import { useBlockProps } from '@wordpress/block-editor';
import metadata from './block.json';
const Edit = () => <p { ...useBlockProps() }>Hello World - 区块编辑器</p>;
const save = () => <p { ...useBlockProps.save() }>Hello World - 前端</p>;
registerBlockType( metadata.name, {
edit: Edit,
save,
} );
```
_查看[上述代码](https://github.com/WordPress/block-development-examples/blob/trunk/plugins/minimal-block-ca6eda/src/index.js)的[完整区块示例](https://github.com/WordPress/block-development-examples/tree/trunk/plugins/minimal-block-ca6eda)_
## 附加资源
- [`register_block_type` PHP函数](https://developer.wordpress.org/reference/functions/register_block_type/)
- [`registerBlockType` JS函数](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-blocks/#registerblocktype)
- [为什么区块需要在服务端和客户端同时注册?](https://github.com/WordPress/gutenberg/discussions/55884) | GitHub讨论
- [区块注册流程图](https://excalidraw.com/#json=PUQu7jpvbKsUHYfpHWn7s,61QnhpZtjykp3s44lbUN_g)