社区新闻

块变体简介

查看官方原文 ↗ 发布于

块变体是扩展WordPress并为用户定制编辑体验最强大的方式之一。在本文中,您将学习如何有效创建块变体,并探索将其融入工作流程的方法。让我们开始吧。

块变体 API

块变体 API 允许您创建现有块的附加版本,这些版本通过一组初始属性或内部块来区分。

变体由一个包含一组属性的对象定义。我将在本文中介绍许多最重要的属性,您可以在块变体 API 文档中查看其余部分。

  • name (类型 string) – 唯一且机器可读的名称。
  • title (可选,类型 string) – 人类可读的变体标题。
  • icon (可选,类型 string | Object) – 编辑器 UI 中变体的图标。
  • attributes (可选,类型 Object) – 覆盖原始块默认属性的值。
  • innerBlocks (可选,类型 Array[]) – 嵌套块的初始配置。
  • isDefault (可选,类型 boolean) – 默认为 false。指示当前变体是否为默认变体。
  • isActive (可选,类型 Function | string[]) – 一个函数或块属性数组,用于确定当块被选中时变体是否处于活动状态。该函数接受 blockAttributesvariationAttributes

一旦定义,可以使用函数 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-blockswp-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

创建包含内部块的变体

现在让我们回到上面的媒体与文本示例。虽然此块变体设置了 alignbackgroundColor 属性,但如果您想向块的文本部分添加默认内容怎么办?

我们可以使用 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'
		}
	}
);

该变体将按预期与默认的媒体与文本块一起出现在插入器中。但是,插入变体后,如果用户再次选择该块,它将被标记为“媒体与文本”而不是“文本与媒体”。

发生这种错误标记是因为编辑器无法区分变体和原始媒体与文本块。如果变体具有自定义的 descriptionicon 属性,问题会加剧,并可能导致用户混淆。

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'),它将理解用户选择了文本与媒体变体。块的描述性信息将相应更新。

未应用 isActive 属性时的块描述。
应用 isActive 属性时的块描述。

如果您在数组中列出多个属性,则将检查每个属性。只有当它们全部匹配时,变体才会被视为“活动”。

添加自定义图标

为了简单起见,之前的示例没有自定义图标。但是,为块变体提供自己的图标是提高其在插入器中可发现性的好方法。您可以使用 icon 属性分配图标,该属性接受字符串或对象。
使用字符串时,它必须与 Dashicon 关联。其他字符串将不起作用。例如,WordPress 图标的 Dashicon 标识是 dashicons-wordpress。移除 dashicons- 前缀并设置 icon: ‘wordpress’ 以使用此图标。结果将如下所示:

使用 Dashicon 作为自定义图标的块变体。

在大多数情况下,您可能希望添加自定义 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 内置的组件和函数——类似于您已经使用 registerBlockVariationunregisterBlockVariationdomReady 所做的那样。

在位于 functions.php 文件中的入队函数中,添加 wp-elementwp-primitives 的依赖项。然后,您可以使用 createElementSVGPath 来创建图标对象。

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' );

本文仅触及了方块变体的表面,但你现在掌握了基础知识,是时候开始自己尝试了。考虑如何在下一个项目中使用变体,并与社区分享你的实现。