块属性提供了关于块存储的数据的信息。例如,富内容、图像 URL 列表、背景颜色或按钮标题。
一个块可以包含任意数量的属性,这些属性由 attributes 字段指定——这是一个对象,其中每个键是属性的名称,值是该属性的定义。
属性定义至少将包含 type 或 enum 之一。可能有其他字段。
示例:定义三个属性的属性对象——url、title 和 size。
{
url: {
type: 'string',
source: 'attribute',
selector: 'img',
attribute: 'src',
},
title: {
type: 'string',
},
size: {
enum: [ 'large', 'small' ],
},
}
当块被解析时,此定义将用于从块内容中提取数据。任何匹配的内容都可以通过 attributes prop 提供给您的块。
此解析过程可以总结为:
- 从
source中提取值。 - 检查值是否匹配
type,或者是enum值之一。
示例:在 edit 和函数中可用的属性,使用上述属性定义。
function YourBlockEdit( { attributes } ) {
return (
<p>URL is { attributes.url }, title is { attributes.title }, and size is { attributes.size }.</p>
)
}
块负责使用 save 函数确保所有具有 source 字段的属性都根据属性定义进行保存。这不是自动的。
没有 source 的属性将自动保存在块的 注释分隔符 中。
例如,使用上述属性定义,您需要确保您的 save 函数为 url 属性具有相应的 img 标签。title 和 size 属性将保存在注释分隔符中。
示例:包含 url 属性的示例 save 函数。
function YourBlockSave( { attributes } ) {
return (
<img src={ attributes.url } />
)
}
保存的 HTML 将包含注释分隔符中的 title 和 size,以及 img 节点中的 url。
<!-- block:your-block {"title":"hello world","size":"large"} -->
<img src="/image.jpg" />
<!-- /block:your-block -->
如果属性随时间变化,则 块弃用 可以帮助从旧属性迁移或完全删除它。
类型验证
type 指示属性存储的数据类型。它不指示数据存储的位置,这由 source 字段定义。
除非提供 enum,否则需要 type。type 可以与 enum 一起使用。
type 字段必须是以下之一:
nullbooleanobjectarraystringintegernumber(与integer相同)
请注意,object 的有效性由您的 source 确定。示例请参见下面的 query 详情。
枚举验证
属性可以定义为固定值集之一。这由 enum 指定,其中包含允许值的数组:
示例:示例 enum。
{
size: {
enum: [ 'large', 'small', 'tiny' ]
}
}
值源
属性源用于定义如何从保存的帖子内容中提取属性值。它们提供了一种机制,将保存的标记映射到块的 JavaScript 表示。
可用的 source 值为:
– (无值) – 当未指定 source 时,数据存储在块的 注释分隔符 中。
– attribute – 数据存储在 HTML 元素属性中。
– text – 数据存储在 HTML 文本中。
– html – 数据存储在 HTML 中。这通常由 RichText 使用。
– query – 数据作为对象数组存储。
– meta – 数据存储在帖子元数据中(已弃用)。
source 字段通常与 selector 字段结合使用。如果未指定选择器参数,则源定义针对块的根节点运行。如果指定了选择器参数,它将针对块内的匹配元素运行。
selector 可以是 HTML 标签,或任何可通过 querySelector 查询的内容,例如类或 id 属性。下面给出了示例。
例如,img 的 selector 将匹配 img 元素,而 img.class 将匹配具有 class 类的 img 元素。
在底层,属性源是 hpq 提供的功能的超集,这是一个用于解析和查询 HTML 标记为对象形状的小型库。
总之,source 确定数据存储在您的内容中的位置,而 type 确定该数据是什么。为了减少存储的数据量,通常最好在 HTML 中存储尽可能多的数据,而不是在注释分隔符中的属性中存储。
attribute 源
使用 attribute 源从标记中的属性提取值。属性由 attribute 字段指定,必须提供该字段。
示例:从块标记中找到的图像中提取 src 属性。
保存的内容:
<div>
Block Content
<img src="https://lorempixel.com/1200/800/" />
</div>
属性定义:
{
url: {
type: 'string',
source: 'attribute',
selector: 'img',
attribute: 'src',
}
}
块中可用的属性:
{ "url": "https://lorempixel.com/1200/800/" }
来自标记的大多数属性类型均为 string。HTML 中的数字属性仍然存储为字符串,并且不会自动转换。
示例:从块标记中找到的图像中提取 width 属性。
保存的内容:
<div>
Block Content
<img src="https://lorempixel.com/1200/800/" width="50" />
</div>
属性定义:
{
width: {
type: 'string',
source: 'attribute',
selector: 'img',
attribute: 'width',
}
}
块中可用的属性:
{ "width": "50" }
唯一的例外是检查属性的存在性(例如,button 上的 disabled 属性)。在这种情况下,可以使用类型 boolean,存储的值将是布尔值。
示例:从块标记中找到的按钮中提取 disabled 属性。
保存的内容:
<div>
Block Content
<button type="button" disabled>Button</button>
</div>
属性定义:
{
disabled: {
type: 'boolean',
source: 'attribute',
selector: 'button',
attribute: 'disabled',
}
}
块中可用的属性:
{ "disabled": true }
text 源
使用 text 从标记中提取内部文本。请注意,HTML 是根据 textContent 的规则返回的。
示例:从块标记中找到的 figcaption 元素中提取 content 属性。
保存的内容:
<figure>
<img src="/image.jpg" />
<figcaption>The inner text of the figcaption element</figcaption>
</figure>
属性定义:
{
content: {
type: 'string',
source: 'text',
selector: 'figcaption',
}
}
块中可用的属性:
{ "content": "The inner text of the figcaption element" }
另一个示例,使用 text 作为源,并使用 .my-content 类作为选择器来提取文本:
示例:从块标记中发现的具有 .my-content 类的元素中提取 content 属性。
保存的内容:
<div>
<img src="/image.jpg" />
<p class="my-content">The inner text of .my-content class</p>
</div>
属性定义:
{
content: {
type: 'string',
source: 'text',
selector: '.my-content',
}
}
块中可用的属性:
{ "content": "The inner text of .my-content class" }
html 源
使用 html 从标记中提取内部 HTML。请注意,文本的返回遵循 innerHTML 的规则。
示例:从块标记中发现的 figcaption 元素中提取 content 属性。
保存的内容:
<figure>
<img src="/image.jpg" />
<figcaption>The inner text of the <strong>figcaption</strong> element</figcaption>
</figure>
属性定义:
{
content: {
type: 'string',
source: 'html',
selector: 'figcaption',
}
}
块中可用的属性:
{ "content": "The inner text of the <strong>figcaption</strong> element" }
query 源
使用 query 从标记中提取值数组。数组的条目由 selector 参数确定,其中块内的每个匹配元素都将有一个条目,其结构对应于第二个参数,即属性源对象。
query 字段实际上是一个嵌套的块属性定义。可以(尽管不一定推荐)进一步嵌套。
示例:从块标记中的每个图像元素中提取 src 和 alt。
保存的内容:
<div>
<img src="https://lorempixel.com/1200/800/" alt="large image" />
<img src="https://lorempixel.com/50/50/" alt="small image" />
</div>
属性定义:
{
images: {
type: 'array',
source: 'query',
selector: 'img',
query: {
url: {
type: 'string',
source: 'attribute',
attribute: 'src',
},
alt: {
type: 'string',
source: 'attribute',
attribute: 'alt',
},
}
}
}
块中可用的属性:
{
"images": [
{ "url": "https://lorempixel.com/1200/800/", "alt": "large image" },
{ "url": "https://lorempixel.com/50/50/", "alt": "small image" }
]
}
Meta 源 (deprecated)
虽然属性可以从帖子的元数据中获取,但元数据属性源被视为已弃用;应使用 EntityProvider 和相关钩子 API,如 创建元数据块教程 所示。属性可以从帖子的元数据中获取,而不是从保存的帖子内容中的块的表示形式中获取。为此,需要一个属性来指定其在 meta 键下的相应元数据键。
属性定义:
{
author: {
type: 'string',
source: 'meta',
meta: 'author'
},
},
从此时起,块可以使用与任何属性相同的接口来读取和写入元数据属性:
edit( { attributes, setAttributes } ) {
function onChange( event ) {
setAttributes( { author: event.target.value } );
}
return <input value={ attributes.author } onChange={ onChange } type="text" />;
},
注意事项
默认情况下,元数据字段将从帖子对象的元数据中排除。可以通过显式使字段可见来绕过这一点:
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 参数,如下所示:
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 字符串。请记住,您有责任确保数据的完整性;请确保正确清理、处理缺失数据等。
最后,在设置属性时,请确保尊重数据的类型,因为框架不会自动对元数据进行类型转换。块属性中的错误类型将导致帖子在保存后仍然保持脏状态(cf. isEditedPostDirty, hasEditedAttributes)。例如,如果 authorCount 是整数,请记住事件处理程序可能会传递不同类型的数据,因此应显式转换该值:
function onChange( event ) {
props.setAttributes( { authorCount: Number( event.target.value ) } );
}
默认值
块属性可以包含默认值,如果 type 和 source 与块内容中的任何内容不匹配,则使用该默认值。
该值由 default 字段提供,并且该值应符合属性的预期格式。
示例:default 值的示例。
{
type: 'string',
default: 'hello world'
}
{
type: 'array',
default: [
{ "url": "https://lorempixel.com/1200/800/", "alt": "large image" },
{ "url": "https://lorempixel.com/50/50/", "alt": "small image" }
]
}
{
type: 'object',
default: {
width: 100,
title: 'title'
}
}
角色
role 属性将属性指定为特定概念类型。此属性可以应用于任何属性,以提供有关应如何处理属性的语义含义。
使用 content 将属性指定为用户可编辑的内容。标记为 content 的块可以在特殊情况下(例如仅内容锁定)启用特权编辑。
使用 local 将属性标记为临时且不可持久化。标记为 local 的属性会被块序列化器忽略,并且永远不会保存到帖子内容中。
示例:段落块使用的 content 角色。
{
content: {
type: 'string',
source: 'html',
selector: 'p',
role: 'content',
}
}
示例:用于临时数据的 local 角色。
{
blob: {
type: 'string',
role: 'local',
}
}
在 WordPress 6.7 开发说明 中了解更多。