块变体简介
块变体是扩展WordPress并为用户定制编辑体验最强大的方式之一。在本文中,您将学习如何有效创建块变体,并探索将其融入工作流程的方法。让我们开始吧。
块变体 API
块变体 API 允许您创建现有块的附加版本,这些版本通过一组初始属性或内部块来区分。
变体由一个包含一组属性的对象定义。我将在本文中介绍许多最重要的属性,您可以在块变体 API 文档中查看其余部分。
- name (类型 string) – 唯一且机器可读的名称。
- title (可选,类型 string) – 人类可读的变体标题。
- icon (可选,类型 string | Object) – 编辑器 UI 中变体的图标。
- attributes (可选,类型 Object) – 覆盖原始块默认属性的值。
- innerBlocks (可选,类型 Array[]) – 嵌套块的初始配置。
- isDefault (可选,类型 boolean) – 默认为 false。指示当前变体是否为默认变体。
- isActive (可选,类型 Function | string[]) – 一个函数或块属性数组,用于确定当块被选中时变体是否处于活动状态。该函数接受
blockAttributes和variationAttributes。
一旦定义,可以使用函数 registerBlockVariation() 创建变体,或使用 unregisterBlockVariation() 注销。下面的示例演示了如何使用两者。
变体也可以在块注册期间声明。有关更多详细信息,请参阅块注册 API。如果您正在构建自定义块并希望提供额外的变体,这种方法很有用。
设置
块变体在 JavaScript 中注册,因此您首先需要创建一个 JavaScript 文件。
我将假设您想向主题添加块变体,但这种方法可以轻松适应插件。唯一的真正区别是文件和函数的位置。现在,让我们创建 variations.js 并将其放在主题的 assets/js 文件夹中。
接下来,您需要使用 enqueue_block_editor_assets 钩子和标准的 wp_equeue_script() 函数来入队 variations.js。除非您有更高级的设置,否则此代码通常应放在主题的 functions.php 文件中。
function example_enqueue_block_variations() {
wp_enqueue_script(
'example-enqueue-block-variations',
get_template_directory_uri() . '/assets/js/variations.js',
array( 'wp-blocks', 'wp-dom-ready' ),
wp_get_theme()->get( 'Version' ),
false
);
}
add_action( 'enqueue_block_editor_assets', 'example_enqueue_block_variations' );
请注意,wp-blocks 和 wp-dom-ready 被列为依赖项。这些将用于在后续步骤中注册和注销块变体,但目前设置已完成。
WordPress 开发者博客通常对 JavaScript 示例使用ESNext 语法。但是,由于通常会将块变体添加到不包含构建过程的主题中,因此此处的示例将使用纯 JavaScript。如果您的项目已有构建过程,请随意使用 ESNext。可以在超越块样式,第 1 部分:在主题中使用 WordPress 脚本包中找到关于此方法的绝佳资源。
创建块变体
随着 variation.js 文件入队,您现在可以使用 registerBlockVariation() 函数注册块变体。此函数来自我之前添加到入队函数的 wp-blocks 依赖项,可以通过在函数前加上 wp.block. 来调用,或者像这样:
const { registerBlockVariation } = wp.blocks;
registerBlockVariation( ... );
使用您喜欢的任何方法——我将在本文中使用 wp.blocks.registerBlockVariation()。
registerBlockVariation() 函数接受原始块的名称和一个定义您要创建的变体的对象。让我们看一个例子。
wp.blocks.registerBlockVariation(
'core/media-text',
{
name: 'media-text-custom',
title: '媒体与文本自定义',
attributes: {
align: 'wide',
backgroundColor: 'tertiary'
},
}
);
上面的代码为媒体与文本块 (core/media-text) 注册了一个块变体。我给它一个唯一的 name 和一个 title,并设置了一些属性值。当此变体插入编辑器时,它将是一个宽对齐的媒体与文本块,背景颜色设置为 tertiary。
从技术上讲,您可以在没有唯一名称的情况下创建块变体,尽管我不建议这样做。唯一的 name 允许编辑器区分您的变体和其他可能存在的变体。
当使用 Twenty Twenty-Three 主题时,变体将如下所示:

您可能已经注意到,媒体与文本块和“媒体与文本自定义”变体都出现在插入器中。这是正确的结果,但您可以添加属性 isDefault: true 以用您的变体替换原始块。当您想要修改核心块或第三方块的初始状态时,此方法非常方便。
让我们更新示例,使变体成为默认值。通过此更改,插入的媒体与文本块始终宽对齐并具有背景颜色。
wp.blocks.registerBlockVariation(
'core/media-text',
{
name: 'media-text-default',
title: '媒体与文本',
attributes: {
align: 'wide',
backgroundColor: 'tertiary'
},
isDefault: true
}
);
由于变体现在是默认值,我已将标题改回“媒体与文本”,插入器现在将只显示一个媒体与文本块。从用户的角度来看,他们只是在使用默认块。

当您使用 isDefault 时,需要注意其他注意事项,特别是如果该块已经有另一个变体设置为 isDefault。有关更多信息,请参阅文档。
注销块变体
许多核心 WordPress 块实际上是变体。例如,组块有四个变体:组、行、堆栈和网格(实验性)。嵌入块和社交图标块也是很好的例子。
有时,您可能不需要站点上的某些块变体。移除这些选择可以简化插入器并改善用户体验。要实现这一点,请使用 unregisterBlockVariation 函数。只需提供原始块名称和要移除的变体 name。
以下代码注销了堆栈块。
wp.domReady( () => {
wp.blocks.unregisterBlockVariation( 'core/group', 'group-stack' );
});
注销核心块时需要使用 wp.domReady。没有它,函数触发得太早,变体永远不会被移除。虽然注销某些第三方块可能不需要 wp.domReady,但一致使用它是一个好主意。注册块变体不需要 wp.domReady。
创建包含内部块的变体
现在让我们回到上面的媒体与文本示例。虽然此块变体设置了 align 和 backgroundColor 属性,但如果您想向块的文本部分添加默认内容怎么办?
我们可以使用 innerBlocks 属性来实现这一点,该属性允许您指定在插入时包含在变体中的块数组。您还可以设置这些内部块的属性。
在下面的示例中,我在原始示例中添加了一个标题块和一个段落块。每个块还有一个占位符。这将帮助用户更一致地创建内容。
wp.blocks.registerBlockVariation(
'core/media-text',
{
name: 'media-text-default',
title: '媒体与文本',
attributes: {
align: 'wide',
backgroundColor: 'tertiary'
},
innerBlocks: [
[
'core/heading',
{
level: 3,
placeholder: '标题'
}
],
[
'core/paragraph',
{
placeholder: '在此输入内容...'
}
],
],
isDefault: true,
}
);
插入时,块变体现在将如下所示:

innerBlocks 属性仅适用于包含其他块的块。但是,当与块和模板锁定结合使用时,此功能可能非常强大。虽然锁定超出了本文的范围,但您可以在策划编辑器体验指南中了解更多信息。
使用 isActive 属性
接下来是 isActive 属性,它帮助编辑器确定变体是否处于活动状态。
为了说明此属性的工作原理,让我们创建一个名为文本与媒体的新块变体。它将类似于之前的示例,但插入时,文本将在左侧,图像在右侧。此行为使用属性 mediaPosition: 'right' 定义。
wp.blocks.registerBlockVariation(
'core/media-text',
{
name: 'text-media',
title: '文本与媒体',
attributes: {
align: 'wide',
backgroundColor: 'tertiary',
mediaPosition: 'right'
}
}
);
该变体将按预期与默认的媒体与文本块一起出现在插入器中。但是,插入变体后,如果用户再次选择该块,它将被标记为“媒体与文本”而不是“文本与媒体”。
发生这种错误标记是因为编辑器无法区分变体和原始媒体与文本块。如果变体具有自定义的 description 和 icon 属性,问题会加剧,并可能导致用户混淆。
isActive 属性提供了一个解决方案,它接受一个函数或一个属性字符串数组。我将在这里使用数组表示法,但您可以参考块变体 API 文档以获取函数示例。
文本与媒体变体主要由 mediaPosition 属性定义,因此让我们设置 isActive: [ ‘mediaPosition’ ]。
wp.blocks.registerBlockVariation(
'core/media-text',
{
name: 'text-media',
title: '文本与媒体',
attributes: {
align: 'wide',
backgroundColor: 'tertiary',
mediaPosition: 'right'
},
isActive: [ 'mediaPosition' ]
}
);
应用此属性后,编辑器将比较所选媒体与文本块的属性与任何已注册的变体。如果它找到一个 mediaPosition 属性与所选块匹配的变体(在本例中为 mediaPosition: 'right'),它将理解用户选择了文本与媒体变体。块的描述性信息将相应更新。


如果您在数组中列出多个属性,则将检查每个属性。只有当它们全部匹配时,变体才会被视为“活动”。
添加自定义图标
为了简单起见,之前的示例没有自定义图标。但是,为块变体提供自己的图标是提高其在插入器中可发现性的好方法。您可以使用 icon 属性分配图标,该属性接受字符串或对象。
使用字符串时,它必须与 Dashicon 关联。其他字符串将不起作用。例如,WordPress 图标的 Dashicon 标识是 dashicons-wordpress。移除 dashicons- 前缀并设置 icon: ‘wordpress’ 以使用此图标。结果将如下所示:

在大多数情况下,您可能希望添加自定义 SVG 图标而不是 Dashicon。这可以通过将对象传递给 icon 属性来实现。
回顾之前创建的文本与媒体示例,图标不能准确表示块变体的默认状态。媒体应该在右侧,而不是左侧。

右侧的图标是使用原始媒体与文本图标并在 Figma 中进行了一些操作创建的。请注意,自定义图标通常应为 24 像素正方形。以下是 SVG 代码。
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M21 17.5L21 6L13 6L13 17.5L21 17.5ZM10 14.5L3 14.5L3 16L10 16L10 14.5ZM3 11L10 11L10 12.5L3 12.5L3 11ZM10 7.5L3 7.5L3 9L10 9L10 7.5Z"></path>
</svg>
您可以在组件 Storybook 中浏览完整的 WordPress 图标库,然后使用浏览器检查器提取 SVG 代码。
下一步是将此 SVG 作为对象添加到 icon 属性中。当使用纯 JavaScript 而不是 ESNext 注册块变体时,这种表示法可能很棘手。您可以在 GitHub 上探索核心块的源代码,以获取大量 ESNext 语法示例,这在此上下文中将不涉及。
使用纯 JavaScript 添加自定义 SVG 的最简单解决方案是利用 WordPress 内置的组件和函数——类似于您已经使用 registerBlockVariation、unregisterBlockVariation 和 domReady 所做的那样。
在位于 functions.php 文件中的入队函数中,添加 wp-element 和 wp-primitives 的依赖项。然后,您可以使用 createElement、SVG 和 Path 来创建图标对象。
const textMediaIcon = wp.element.createElement(
wp.primitives.SVG,
{ xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24" },
wp.element.createElement(
wp.primitives.Path,
{
d: "M21 17.5L21 6L13 6L13 17.5L21 17.5ZM10 14.5L3 14.5L3 16L10 16L10 14.5ZM3 11L10 11L10 12.5L3 12.5L3 11ZM10 7.5L3 7.5L3 9L10 9L10 7.5Z",
}
)
);
代码可能看起来有点复杂,但将其与上面的原始 SVG 标记进行比较,您将能够发现相似之处。
最后,设置 icon: textMediaIcon,结果将如下所示:

整合所有内容
结合本文中的所有示例,您最终的 variations.js 文件将:
- 添加一个带有内部块和彩色背景的媒体与文本块变体,该变体设置为
isDefault。 - 添加一个带有自定义图标的文本与媒体块变体,以演示
isActive。 - 注销组块的核心堆栈变体。
以下是完整的variations.js文件:
// 注册一个新的默认媒体与文本块变体。
wp.blocks.registerBlockVariation(
'core/media-text',
{
name: 'media-text-default',
title: '媒体与文本',
attributes: {
align: 'wide',
backgroundColor: 'tertiary'
},
innerBlocks: [
[
'core/heading',
{
level: 3,
placeholder: '标题'
}
],
[
'core/paragraph',
{
placeholder: '在此输入内容...'
}
],
],
isDefault: true,
}
);
// 定义文本与媒体块变体的图标。
const textMediaIcon = wp.element.createElement(
wp.primitives.SVG,
{ xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24" },
wp.element.createElement(
wp.primitives.Path,
{
d: "M21 17.5L21 6L13 6L13 17.5L21 17.5ZM10 14.5L3 14.5L3 16L10 16L10 14.5ZM3 11L10 11L10 12.5L3 12.5L3 11ZM10 7.5L3 7.5L3 9L10 9L10 7.5Z",
}
)
);
// 注册文本与媒体块变体。
wp.blocks.registerBlockVariation(
'core/media-text',
{
name: 'text-media',
title: '文本与媒体',
icon: textMediaIcon,
attributes: {
align: 'wide',
backgroundColor: 'tertiary',
mediaPosition: 'right'
},
isActive: [ 'mediaPosition' ]
}
);
// 注销堆栈块变体。
wp.domReady( () => {
unregisterBlockVariation( 'core/group', 'group-stack' );
});
最后,这应该被列入你的主题文件,并附带必要的依赖关系。在functions.php中注册并引入variations.js
functions.phpfunction example_enqueue_block_variations() {
wp_enqueue_script(
'example-enqueue-block-variations',
get_template_directory_uri() . '/assets/js/variations.js',
array( 'wp-blocks', 'wp-dom-ready', 'wp-element', 'wp-primitives' ),
wp_get_theme()->get( 'Version' ),
false
);
}
add_action( 'enqueue_block_editor_assets', 'example_enqueue_block_variations' );
本文仅触及了方块变体的表面,但你现在掌握了基础知识,是时候开始自己尝试了。考虑如何在下一个项目中使用变体,并与社区分享你的实现。