# 区块注册

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)