495 lines
13 KiB
Markdown
495 lines
13 KiB
Markdown
|
|
# 属性
|
|||
|
|
|
|||
|
|
区块属性提供了关于区块存储数据的信息。例如:富文本内容、图片URL列表、背景色或按钮标题。
|
|||
|
|
|
|||
|
|
一个区块可以包含任意数量的属性,这些属性通过`attributes`字段指定——该对象中的每个键都是属性名称,值则是属性定义。
|
|||
|
|
|
|||
|
|
属性定义至少包含`type`或`enum`之一,也可能包含其他字段。
|
|||
|
|
|
|||
|
|
*示例*:定义三个属性(`url`、`title`和`size`)的属性对象。
|
|||
|
|
|
|||
|
|
```js
|
|||
|
|
{
|
|||
|
|
url: {
|
|||
|
|
type: 'string',
|
|||
|
|
source: 'attribute',
|
|||
|
|
selector: 'img',
|
|||
|
|
attribute: 'src',
|
|||
|
|
},
|
|||
|
|
title: {
|
|||
|
|
type: 'string',
|
|||
|
|
},
|
|||
|
|
size: {
|
|||
|
|
enum: [ 'large', 'small' ],
|
|||
|
|
},
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
当区块被解析时,此定义将用于从区块内容中提取数据。所有匹配项都会通过`attributes`属性提供给您的区块。
|
|||
|
|
|
|||
|
|
该解析过程可概括为:
|
|||
|
|
|
|||
|
|
1. 从`source`中提取值
|
|||
|
|
2. 检查值是否匹配`type`,或是`enum`值之一
|
|||
|
|
|
|||
|
|
*示例*:使用上述属性定义,在`edit`函数中可用的属性。
|
|||
|
|
|
|||
|
|
```js
|
|||
|
|
function YourBlockEdit( { attributes } ) {
|
|||
|
|
return (
|
|||
|
|
<p>URL是{ attributes.url },标题是{ attributes.title },尺寸是{ attributes.size }。</p>
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
区块需负责使用`save`函数确保所有带`source`字段的属性按照属性定义保存。此过程非自动执行。
|
|||
|
|
|
|||
|
|
没有`source`的属性将自动保存在区块[注释分隔符](/docs/explanations/architecture/key-concepts.md#data-attributes)中。
|
|||
|
|
|
|||
|
|
例如,使用上述属性定义时,您需要确保`save`函数包含与`url`属性对应的img标签。`title`和`size`属性将保存在注释分隔符中。
|
|||
|
|
|
|||
|
|
*示例*:包含`url`属性的`save`函数示例
|
|||
|
|
|
|||
|
|
```js
|
|||
|
|
function YourBlockSave( { attributes } ) {
|
|||
|
|
return (
|
|||
|
|
<img src={ attributes.url } />
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
保存的HTML将在注释分隔符中包含`title`和`size`,在`img`节点中包含`url`。
|
|||
|
|
|
|||
|
|
```html
|
|||
|
|
<!-- block:your-block {"title":"hello world","size":"large"} -->
|
|||
|
|
<img src="/image.jpg" />
|
|||
|
|
<!-- /block:your-block -->
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
若属性随时间变化,可通过[区块弃用](/docs/reference-guides/block-api/block-deprecation.md)来迁移旧属性或完全移除。
|
|||
|
|
|
|||
|
|
## 类型验证
|
|||
|
|
|
|||
|
|
`type`指明属性存储的数据类型。它不表示数据存储位置(由`source`字段定义)。
|
|||
|
|
|
|||
|
|
除非提供`enum`,否则`type`是必需的。`type`可与`enum`同时使用。
|
|||
|
|
|
|||
|
|
`type`字段必须是以下之一:
|
|||
|
|
|
|||
|
|
- `null`
|
|||
|
|
- `boolean`
|
|||
|
|
- `object`
|
|||
|
|
- `array`
|
|||
|
|
- `string`
|
|||
|
|
- `integer`
|
|||
|
|
- `number`(与`integer`相同)
|
|||
|
|
|
|||
|
|
注意:`object`的有效性由您的`source`决定。示例可参阅下文的`query`详情。
|
|||
|
|
|
|||
|
|
## 枚举验证
|
|||
|
|
|
|||
|
|
属性可定义为固定值集合中的一个值。通过包含允许值数组的`enum`来指定:
|
|||
|
|
|
|||
|
|
*示例*:`enum`示例。
|
|||
|
|
|
|||
|
|
```js
|
|||
|
|
{
|
|||
|
|
size: {
|
|||
|
|
enum: [ 'large', 'small', 'tiny' ]
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 值来源
|
|||
|
|
|
|||
|
|
属性来源用于定义如何从已保存的文章内容中提取属性值。它们提供了一种从已保存标记到区块JavaScript表示的映射机制。
|
|||
|
|
|
|||
|
|
可用的`source`值包括:
|
|||
|
|
- `(无值)`- 未指定`source`时,数据存储在区块的[注释分隔符](/docs/explanations/architecture/key-concepts.md#data-attributes)中
|
|||
|
|
- `attribute`- 数据存储在HTML元素属性中
|
|||
|
|
- `text`- 数据存储在HTML文本中
|
|||
|
|
- `html`- 数据以HTML形式存储(通常由`RichText`使用)
|
|||
|
|
- `query`- 数据以对象数组形式存储
|
|||
|
|
- `meta`- 数据存储在文章元数据中(已弃用)
|
|||
|
|
|
|||
|
|
`source`字段通常与`selector`字段结合使用。若未指定选择器参数,源定义将针对区块根节点运行。若指定选择器参数,则将针对区块内的匹配元素运行。
|
|||
|
|
|
|||
|
|
`selector`可以是HTML标签,或任何可通过[querySelector](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector)查询的内容,例如类或id属性。下方提供了示例。
|
|||
|
|
|
|||
|
|
例如,`img`选择器将匹配`img`元素,而`img.class`将匹配具有`class`类的`img`元素。
|
|||
|
|
|
|||
|
|
在底层实现中,属性来源是[hpq](https://github.com/aduth/hpq)库功能的超集,该小型库用于将HTML标记解析和查询为对象形态。
|
|||
|
|
|
|||
|
|
总结而言,`source`决定数据在内容中的存储位置,而`type`决定数据的类型。为减少存储数据量,通常建议尽可能将数据存储在HTML中而非注释分隔符内的属性中。
|
|||
|
|
|
|||
|
|
### 元数据源(已弃用)
|
|||
|
|
|
|||
|
|
<div class="callout callout-alert">
|
|||
|
|
虽然属性可从文章的元数据中获取,但元数据属性源已被视为弃用;应改用 <a href="https://github.com/WordPress/gutenberg/blob/c367c4e2765f9e6b890d1565db770147efca5d66/packages/core-data/src/entity-provider.js">EntityProvider 及相关钩子 API</a>,如 <a href="https://developer.wordpress.org/block-editor/how-to-guides/metabox/#step-2-add-meta-block">创建元数据块指南</a> 中所示。
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
属性可从文章的元数据中获取,而非从已保存文章内容中的块表示中获取。为此,需要为属性在 `meta` 键下指定其对应的元数据键。
|
|||
|
|
|
|||
|
|
属性定义:
|
|||
|
|
```js
|
|||
|
|
{
|
|||
|
|
author: {
|
|||
|
|
type: 'string',
|
|||
|
|
source: 'meta',
|
|||
|
|
meta: 'author'
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
从此处开始,元数据属性可以通过与任何属性相同的接口由块读取和写入:
|
|||
|
|
|
|||
|
|
```js
|
|||
|
|
edit( { attributes, setAttributes } ) {
|
|||
|
|
function onChange( event ) {
|
|||
|
|
setAttributes( { author: event.target.value } );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return <input value={ attributes.author } onChange={ onChange } type="text" />;
|
|||
|
|
},
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 注意事项
|
|||
|
|
|
|||
|
|
默认情况下,元字段将从文章对象的元数据中排除。可以通过显式使字段可见来规避此问题:
|
|||
|
|
|
|||
|
|
```php
|
|||
|
|
function gutenberg_my_block_init() {
|
|||
|
|
register_post_meta( 'post', 'author', array(
|
|||
|
|
'show_in_rest' => true,
|
|||
|
|
) );
|
|||
|
|
}
|
|||
|
|
add_action( 'init', 'gutenberg_my_block_init' );
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
此外,请注意 WordPress 默认行为为:
|
|||
|
|
|
|||
|
|
- 不将元数据视为唯一,而是返回值的数组;
|
|||
|
|
- 将该数据视为字符串。
|
|||
|
|
|
|||
|
|
如果不希望出现上述任一行为,可以在相同的 `register_post_meta` 调用中补充 `single` 和/或 `type` 参数,如下所示:
|
|||
|
|
|
|||
|
|
```php
|
|||
|
|
function gutenberg_my_block_init() {
|
|||
|
|
register_post_meta( 'post', 'author_count', array(
|
|||
|
|
'show_in_rest' => true,
|
|||
|
|
'single' => true,
|
|||
|
|
'type' => 'integer',
|
|||
|
|
) );
|
|||
|
|
}
|
|||
|
|
add_action( 'init', 'gutenberg_my_block_init' );
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
如果希望在属性中使用对象或数组,可以注册一个 `string` 属性类型并使用 JSON 作为中间格式。在保存之前将结构化数据序列化为 JSON,然后在服务器上反序列化 JSON 字符串。请注意,您需要负责数据的完整性;确保正确清理数据、处理缺失数据等。
|
|||
|
|
|
|||
|
|
最后,请确保在设置属性时尊重数据的类型,因为框架不会自动执行元数据的类型转换。块属性中的类型错误将导致文章即使在保存后仍保持“脏”状态(参见 `isEditedPostDirty`、`hasEditedAttributes`)。例如,如果 `authorCount` 是整数类型,请记住事件处理程序可能会传递不同类型的数据,因此应显式转换值:
|
|||
|
|
|
|||
|
|
```js
|
|||
|
|
function onChange( event ) {
|
|||
|
|
props.setAttributes( { authorCount: Number( event.target.value ) } );
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 默认值
|
|||
|
|
|
|||
|
|
块属性可以包含默认值,当 `type` 和 `source` 与块内容中的任何内容不匹配时,将使用该值。
|
|||
|
|
|
|||
|
|
该值由 `default` 字段提供,并且该值应与属性的预期格式匹配。
|
|||
|
|
|
|||
|
|
_示例_:`default` 值的示例。
|
|||
|
|
|
|||
|
|
```js
|
|||
|
|
{
|
|||
|
|
type: 'string',
|
|||
|
|
default: 'hello world'
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
```js
|
|||
|
|
{
|
|||
|
|
type: 'array',
|
|||
|
|
default: [
|
|||
|
|
{ "url": "https://lorempixel.com/1200/800/", "alt": "大图" },
|
|||
|
|
{ "url": "https://lorempixel.com/50/50/", "alt": "小图" }
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
```js
|
|||
|
|
{
|
|||
|
|
type: 'object',
|
|||
|
|
default: {
|
|||
|
|
width: 100,
|
|||
|
|
title: '标题'
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 角色
|
|||
|
|
|
|||
|
|
`role` 属性将属性指定为特定概念类型。此属性可应用于任何属性,以提供关于应如何处理该属性的语义含义。
|
|||
|
|
|
|||
|
|
使用 `content` 将属性指定为用户可编辑的内容。在特殊情况下(例如仅内容锁定),标记为 `content` 的块可能被启用为特权编辑。
|
|||
|
|
使用 `local` 将属性标记为临时且不可持久化的。标记为 `local` 的属性会被块序列化器忽略,并且永远不会保存到文章内容中。
|
|||
|
|
|
|||
|
|
_示例_:段落块使用的 `content` 角色
|
|||
|
|
|
|||
|
|
```js
|
|||
|
|
{
|
|||
|
|
content: {
|
|||
|
|
type: 'string',
|
|||
|
|
source: 'html',
|
|||
|
|
selector: 'p',
|
|||
|
|
role: 'content',
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
_示例_:用于临时数据的 `local` 角色。
|
|||
|
|
|
|||
|
|
```js
|
|||
|
|
{
|
|||
|
|
blob: {
|
|||
|
|
type: 'string',
|
|||
|
|
role: 'local',
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
更多信息请参阅 [WordPress 6.7 开发说明](https://make.wordpress.org/core/2024/10/20/miscellaneous-block-editor-changes-in-wordpress-6-7/#stabilized-role-property-for-block-attributes)。
|
|||
|
|
|
|||
|
|
### `attribute` 数据源
|
|||
|
|
|
|||
|
|
使用 `attribute` 数据源可从标记中提取属性值。通过必须提供的 `attribute` 字段指定需要提取的属性。
|
|||
|
|
|
|||
|
|
_示例_:从区块标记中的图片元素提取 `src` 属性。
|
|||
|
|
|
|||
|
|
保存内容:
|
|||
|
|
```html
|
|||
|
|
<div>
|
|||
|
|
区块内容
|
|||
|
|
|
|||
|
|
<img src="https://lorempixel.com/1200/800/" />
|
|||
|
|
</div>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
属性定义:
|
|||
|
|
```js
|
|||
|
|
{
|
|||
|
|
url: {
|
|||
|
|
type: 'string',
|
|||
|
|
source: 'attribute',
|
|||
|
|
selector: 'img',
|
|||
|
|
attribute: 'src',
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
区块中可用的属性:
|
|||
|
|
```js
|
|||
|
|
{ "url": "https://lorempixel.com/1200/800/" }
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
大多数标记中的属性都是字符串类型。HTML中的数值属性仍会以字符串形式存储,且不会自动转换。
|
|||
|
|
|
|||
|
|
_示例_:从区块标记中的图片元素提取 `width` 属性。
|
|||
|
|
|
|||
|
|
保存内容:
|
|||
|
|
```html
|
|||
|
|
<div>
|
|||
|
|
区块内容
|
|||
|
|
|
|||
|
|
<img src="https://lorempixel.com/1200/800/" width="50" />
|
|||
|
|
</div>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
属性定义:
|
|||
|
|
```js
|
|||
|
|
{
|
|||
|
|
width: {
|
|||
|
|
type: 'string',
|
|||
|
|
source: 'attribute',
|
|||
|
|
selector: 'img',
|
|||
|
|
attribute: 'width',
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
区块中可用的属性:
|
|||
|
|
```js
|
|||
|
|
{ "width": "50" }
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
唯一例外是检查属性是否存在的情况(例如检查 `button` 上的 `disabled` 属性)。此时可使用 `boolean` 类型,存储值将转换为布尔值。
|
|||
|
|
|
|||
|
|
_示例_:从区块标记中的按钮元素提取 `disabled` 属性。
|
|||
|
|
|
|||
|
|
保存内容:
|
|||
|
|
```html
|
|||
|
|
<div>
|
|||
|
|
区块内容
|
|||
|
|
|
|||
|
|
<button type="button" disabled>按钮</button>
|
|||
|
|
</div>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
属性定义:
|
|||
|
|
```js
|
|||
|
|
{
|
|||
|
|
disabled: {
|
|||
|
|
type: 'boolean',
|
|||
|
|
source: 'attribute',
|
|||
|
|
selector: 'button',
|
|||
|
|
attribute: 'disabled',
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
区块中可用的属性:
|
|||
|
|
```js
|
|||
|
|
{ "disabled": true }
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### `text` 数据源
|
|||
|
|
|
|||
|
|
使用 `text` 可从标记中提取内部文本。注意返回的HTML内容遵循 [`textContent`](https://developer.mozilla.org/zh-CN/docs/Web/API/Node/textContent) 规则。
|
|||
|
|
|
|||
|
|
_示例_:从区块标记中的 figcaption 元素提取 `content` 属性。
|
|||
|
|
|
|||
|
|
保存内容:
|
|||
|
|
```html
|
|||
|
|
<figure>
|
|||
|
|
<img src="/image.jpg" />
|
|||
|
|
|
|||
|
|
<figcaption>figcaption 元素的内部文本</figcaption>
|
|||
|
|
</figure>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
属性定义:
|
|||
|
|
```js
|
|||
|
|
{
|
|||
|
|
content: {
|
|||
|
|
type: 'string',
|
|||
|
|
source: 'text',
|
|||
|
|
selector: 'figcaption',
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
区块中可用的属性:
|
|||
|
|
```js
|
|||
|
|
{ "content": "figcaption 元素的内部文本" }
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
另一个使用 `text` 数据源,通过 `.my-content` 类选择器提取文本的示例:
|
|||
|
|
|
|||
|
|
_示例_:从区块标记中具有 `.my-content` 类的元素提取 `content` 属性。
|
|||
|
|
|
|||
|
|
保存内容:
|
|||
|
|
```html
|
|||
|
|
<div>
|
|||
|
|
<img src="/image.jpg" />
|
|||
|
|
|
|||
|
|
<p class="my-content">.my-content 类的内部文本</p>
|
|||
|
|
</div>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
属性定义:
|
|||
|
|
```js
|
|||
|
|
{
|
|||
|
|
content: {
|
|||
|
|
type: 'string',
|
|||
|
|
source: 'text',
|
|||
|
|
selector: '.my-content',
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
区块中可用的属性:
|
|||
|
|
```js
|
|||
|
|
{ "content": ".my-content 类的内部文本" }
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### `html` 数据源
|
|||
|
|
|
|||
|
|
使用 `html` 可从标记中提取内部HTML。注意返回的文本内容遵循 [`innerHTML`](https://developer.mozilla.org/zh-CN/docs/Web/API/Element/innerHTML) 规则。
|
|||
|
|
|
|||
|
|
_示例_:从区块标记中的 figcaption 元素提取 `content` 属性。
|
|||
|
|
|
|||
|
|
保存内容:
|
|||
|
|
```html
|
|||
|
|
<figure>
|
|||
|
|
<img src="/image.jpg" />
|
|||
|
|
|
|||
|
|
<figcaption><strong>figcaption</strong> 元素的内部文本</figcaption>
|
|||
|
|
</figure>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
属性定义:
|
|||
|
|
```js
|
|||
|
|
{
|
|||
|
|
content: {
|
|||
|
|
type: 'string',
|
|||
|
|
source: 'html',
|
|||
|
|
selector: 'figcaption',
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
区块中可用的属性:
|
|||
|
|
```js
|
|||
|
|
{ "content": "<strong>figcaption</strong> 元素的内部文本" }
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### `query` 数据源
|
|||
|
|
|
|||
|
|
使用 `query` 可从标记中提取值数组。数组条目由 `selector` 参数决定,区块内每个匹配元素都会对应一个条目,其结构由第二个参数(属性源对象)定义。
|
|||
|
|
|
|||
|
|
`query` 字段实际上是嵌套的区块属性定义。虽然可以进一步嵌套(但不一定推荐这样做)。
|
|||
|
|
|
|||
|
|
_示例_:从区块标记中的每个图片元素提取 `src` 和 `alt` 属性。
|
|||
|
|
|
|||
|
|
保存内容:
|
|||
|
|
```html
|
|||
|
|
<div>
|
|||
|
|
<img src="https://lorempixel.com/1200/800/" alt="大图" />
|
|||
|
|
<img src="https://lorempixel.com/50/50/" alt="小图" />
|
|||
|
|
</div>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
属性定义:
|
|||
|
|
```js
|
|||
|
|
{
|
|||
|
|
images: {
|
|||
|
|
type: 'array',
|
|||
|
|
source: 'query',
|
|||
|
|
selector: 'img',
|
|||
|
|
query: {
|
|||
|
|
url: {
|
|||
|
|
type: 'string',
|
|||
|
|
source: 'attribute',
|
|||
|
|
attribute: 'src',
|
|||
|
|
},
|
|||
|
|
alt: {
|
|||
|
|
type: 'string',
|
|||
|
|
source: 'attribute',
|
|||
|
|
attribute: 'alt',
|
|||
|
|
},
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
区块中可用的属性:
|
|||
|
|
```js
|
|||
|
|
{
|
|||
|
|
"images": [
|
|||
|
|
{ "url": "https://lorempixel.com/1200/800/", "alt": "大图" },
|
|||
|
|
{ "url": "https://lorempixel.com/50/50/", "alt": "小图" }
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
```
|