gutenbergdocs/docs/getting-started/fundamentals/registration-of-a-block.md
2025-10-22 01:40:18 +08:00

122 lines
6.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 区块注册
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)