# 区块包装器

区块编辑器中的每个区块都包含在HTML包装器中，该包装器必须具备特定属性才能在编辑器和前端正常运作。作为开发者，我们可以直接操作这些标记，WordPress提供了诸如`useBlockProps()`等工具来修改添加到区块包装器的属性。

在使用自定义样式或[区块支持](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-supports/)等功能时，确保区块包装器具有正确的属性尤为重要。

WordPress中的区块可以通过三种不同类型的标记来定义，每种标记都有其独特作用：

- **编辑器标记**：这是区块在区块编辑器中的可视化呈现。当通过[`registerBlockType`](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-registration/#registerblocktype)在客户端注册区块时，使用React的`Edit`组件来定义。
- **保存标记**：这是保存区块内容时存入数据库的标记。通过提供给`registerBlockType`的`save`函数来指定。如果区块不使用动态渲染，前端将显示此保存的标记。
- **动态渲染标记**：当区块内容需要动态生成时，将使用此标记。它在服务端定义，可以通过[`register_block_type`](https://developer.wordpress.org/reference/functions/register_block_type/)中的`render_callback`函数，或`block.json`中指定的[`render.php`](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/#render)文件来定义。如果存在，此标记将覆盖任何已保存的标记，并用于区块的前端显示。

对于[`Edit`组件和`save`函数](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-edit-save/)，重要的是使用标准DOM元素（如`<div>`）或将所有附加属性传递给原生DOM元素的React组件作为包装器元素。使用React片段（`<Fragment>`）或`<ServerSideRender>`组件不适用于这些包装器。

## 编辑器标记

[`@wordpress/block-editor`](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-block-editor)包提供的[`useBlockProps()`](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-block-editor/#useblockprops)钩子，用于在`Edit`组件中定义区块的外部标记。

此钩子简化了多项任务，包括：

- 为区块的HTML结构分配唯一的`id`
- 添加各种可访问性和`data-`属性以增强功能和信息
- 包含反映区块自定义设置的类和内联样式。默认情况下包括：
    - 用于通用区块样式的`wp-block`类
    - 结合区块命名空间和名称的特定区块类，确保唯一且有目标的样式能力

在以下示例中，区块的编辑器标记在`Edit`组件中使用`useBlockProps()`钩子定义。

```js
const Edit = () => <p { ...useBlockProps() }>Hello World - 区块编辑器</p>;

registerBlockType( ..., {
	edit: Edit
} );
```

_查看[上述代码](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)。_

区块在区块编辑器中的标记可能如下所示，其中类和属性会自动应用：

```html
<p
    tabindex="0"
    id="block-4462939a-b918-44bb-9b7c-35a0db5ab8fe"
    role="document"
    aria-label="区块：Minimal Gutenberg Block ca6eda"
    data-block="4462939a-b918-44bb-9b7c-35a0db5ab8fe"
    data-type="block-development-examples/minimal-block-ca6eda"
    data-title="Minimal Gutenberg Block ca6eda"
    class="
        block-editor-block-list__block
        wp-block
        is-selected
        wp-block-block-development-examples-minimal-block-ca6eda
    "
>Hello World - 区块编辑器</p>
```

在区块的`Edit`组件中，使用`useBlockProps()`钩子并通过传递参数来包含额外的类和属性。（参见[示例](https://github.com/WordPress/block-development-examples/blob/trunk/plugins/stylesheets-79a4c3/src/edit.js)）

当使用`supports`属性启用功能时，任何相应的类或属性都会自动包含在`useBlockProps`返回的对象中。

## 保存标记

在数据库中保存标记时，重要的是将`useBlockProps.save()`返回的属性添加到区块的包装元素中。`useBlockProps.save()`确保区块类名正确渲染，同时还包括区块支持API注入的任何HTML属性。

考虑以下在客户端注册区块的代码。注意它如何定义编辑区块和将区块保存到数据库时应使用的标记。

```js
const Edit = () => <p { ...useBlockProps() }>Hello World - 区块编辑器</p>;
const save = () => <p { ...useBlockProps.save() }>Hello World - 前端</p>;

registerBlockType( ..., {
	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)。_

区块在前端的标记可能如下所示，其中类会自动应用：

```html
<p class="wp-block-block-development-examples-minimal-block-ca6eda">Hello World – 前端</p>
```

如果要在区块的`save`函数中添加任何额外的类或属性，应将它们作为`useBlockProps.save()`的参数传递。（参见[示例](https://github.com/WordPress/block-development-examples/blob/trunk/plugins/stylesheets-79a4c3/src/save.js)）

当为任何功能添加`supports`时，适当的类会添加到`useBlockProps.save()`钩子返回的对象中。在下面的示例中，文本和背景颜色类已添加到段落区块中。

```html
<p class="
    wp-block-block-development-examples-block-supports-6aa4dd
    has-accent-4-color
    has-contrast-background-color
    has-text-color
    has-background
">Hello World</p>
```

生成此HTML的[示例区块](https://github.com/WordPress/block-development-examples/tree/trunk/plugins/block-supports-6aa4dd)可在[区块开发示例](https://github.com/WordPress/block-development-examples)存储库中找到。

## 动态渲染标记

在动态区块中，前端标记在服务端渲染，您可以使用[`get_block_wrapper_attributes()`](https://developer.wordpress.org/reference/functions/get_block_wrapper_attributes/)函数输出必要的类和属性，就像在`save`函数中使用`useBlockProps.save()`一样。（参见[示例](https://github.com/WordPress/block-development-examples/blob/f68640f42d993f0866d1879f67c73910285ca114/plugins/block-dynamic-rendering-64756b/src/render.php#L11)）

```php
<p <?php echo get_block_wrapper_attributes(); ?>>
	<?php esc_html_e( '动态渲染区块 – hello!!!', 'block-development-examples' ); ?>
</p>
```