区块变体API是一项强大的功能,它允许您扩展任何已注册的区块。基本上,它能让您为某个区块的设置创建不同的版本,这样一来,用户在插入区块时就不必再为特定场景繁琐地进行各种设置。

Block Variations API通常被视为插件开发人员专用的API。在很多情况下,插件确实是存放这些变体版本的理想场所,不过主题创建者也有适用它的场景。

WordPress的许多功能名称中都包含“variations”这个词,这有时会让人感到困惑。需要特别注意的是,区块变体与全局样式变体以及区块样式变体并非同一概念。

什么是区块变体?

最简单的解释就是,区块变体其实就是对现有区块的多样化修改。我们通过一个例子来进一步了解这一点。

“社交图标”区块是一种用于添加社交网站链接的简单区块,但WordPress为涵盖各种不同的社交平台,提供了该基础区块的诸多变体版本:

WordPress文章编辑器中显示有多个排成一行的社交图标。

如果没有Block Variations API,那么每一个变体版本都得作为独立的区块来单独编写代码,而这显然有很多弊端。因此,开发者无需为每个社交图标都创建一个单独的区块,只需对原始区块进行少量配置调整,就能生成其变体版本。

实际上,有多种方法可以让区块与其默认配置有所不同。这些方法可能简单到只是使用主题预设的间距来设置“间隔符”区块,也可能复杂到为首页模板创建带有复杂文章查询功能的自定义“查询循环”区块。

虽然这项功能比某些主题功能更为高级,但它确实能让您创建出比默认版本更复杂的主题。

区块变体与区块样式

一个经常被问到的问题是:我应该在什么时候创建区块变体,又应该在什么时候创建区块样式?

答案几乎总与另一个问题的答案相同:这些更改能否通过theme.json中的样式或CSS来实现?如果可以,那几乎总是应该创建自定义的区块样式。

但如果您需要修改区块的设置,以便用户在文章中插入该区块时能得到不同的呈现效果,那么创建自定义的区块变体很可能是最佳选择。

使用区块变体

处理区块变体时需要使用JavaScript而非PHP。下面的示例无需任何构建流程,因此可以直接使用。

不过,随着您越来越多地使用WordPress的JavaScript相关功能,您可能会希望将构建工具整合到自己的工作流程中。原本用于区块开发的@wordpress/scripts包也可以在主题中使用。如需深入了解其工作原理,请阅读《超越区块样式,第一部分:在主题中使用WordPress scripts包》这篇文章。

在接下来的章节中,您将通过在WordPress的“间隔符”区块上创建一个简单的变体来学习如何使用区块变体,如下图所示:

WordPress文章编辑器中包含目录区块、间隔符区块以及演示内容。

如需更深入地了解区块变体,可以查看WordPress开发者博客上的以下教程:

设置:加载JavaScript

要使用区块变体,首先需要创建一个空文件来存放自定义JavaScript代码。这个文件可以放在您选择的任何位置,但下面的代码示例会尝试在主题的/assets/js文件夹中查找名为block-variations.js的文件。

因此,您的主题结构应该类似如下所示:

  • /assets
    • /js
      • /block-variations.js
  • …其他文件和文件夹

要在编辑器中加载该文件,必须在一个添加到enqueue_block_editor_assets动作钩子中的回调函数里,调用wp_enqueue_script()函数。

请将以下代码添加到主题的functions.php文件中:

add_action( 'enqueue_block_editor_assets', 'themeslug_enqueue_block_variations' );

function themeslug_enqueue_block_variations() {
	wp_enqueue_script(
		'themeslug-block-variations',
		get_theme_file_uri( 'assets/js/block-variations.js' ),
		array( 
			'wp-blocks', 
			'wp-dom-ready',
			'wp-i18n'
		),
		wp_get_theme()->get( 'Version' ),
		true
	);
}

请注意wp_enqueue_script()函数中的依赖项数组(第三个参数)。其中包含了wp-blocks、wp-dom-ready和wp-i18n这些脚本,它们是下面示例中的JavaScript代码所必需的。

注册区块变体

要注册区块变体,必须使用registerBlockVariation() JavaScript函数。以下是该函数的签名:

const registerBlockVariation = ( blockName, variation )

该函数接受两个参数:

  • blockName:要为其注册变体的区块名称(包括命名空间)。
  • variation:一个用于配置变体的可选对象,其中可能包含以下属性:
    • name:该变体的唯一、机器可读的标识符。
    • title:该变体的可读标题,需要进行国际化处理。
    • description:该变体的可读描述,如果存在的话也需要进行国际化处理。
    • category:已注册的区块类型类别的标识符。
    • keywords:一组关键词,有助于用户在搜索时找到该变体。
    • icon:用于可视化展示该变体的图标,可以是字符串形式,也可以是对象形式。
    • attributes:一个用于覆盖区块原有属性的对象。
    • innerBlocks:一个数组,用于处理嵌套区块的初始配置。
    • example:一个对象,为区块预览提供结构化数据。可设置为undefined以禁用预览功能。
    • scope:该区块可以使用的范围列表,可选值包括:block、inserter和transform。
    • isDefault:是否将该变体设置为该区块的默认版本,默认值为false。
    • isActive:一个函数或区块属性数组,用于在选中该区块时判断该变体是否处于激活状态。

如需了解更多关于区块变体的信息,请阅读《区块编辑器手册》中的Block Variations API文档。

在创建自定义变体时,最重要的是思考那些您希望控制的属性,正是这些属性让该变体有别于默认区块。这才是构成“变体”的关键所在。

对于“间隔符”区块的变体来说,最可能的控制属性就是height。假设您希望它的默认值为180px,那么对于您的变体,就需要设置attributes.height,同时还在isActive回调函数中检查该属性的值是否为180px。

您可以在block-variations.js文件中粘贴以下代码来尝试实现这一点:

const { registerBlockVariation } = wp.blocks;
const { __ } = wp.i18n;

registerBlockVariation( 'core/spacer', {
	name:       'themeslug/spacer',
	title:      __( 'Theme Name: Spacer', 'themeslug' ),
	keywords:   [ 'space', 'spacer', 'spacing' ],
	attributes: {
		height: '180px'
	},
	isActive: ( blockAttributes ) =>
		blockAttributes.height && '180px' === blockAttributes.height
} );

每个区块都有其自身的属性,因此您需要深入研究该区块的代码,才能确定所有可能想要为变体覆盖的属性。这部分内容超出了本文档的覆盖范围,但上面的代码示例应该能为您提供一个良好的起点。

取消注册区块变体

要取消注册区块变体,必须使用unregisterBlockVariation() JavaScript函数。以下是该函数的签名:

const unregisterBlockVariation = ( blockName, variationName )

该函数接受两个参数:

  • blockName:您想要取消注册的变体所对应的区块名称(包括命名空间)。
  • variationName:要取消注册的变体名称。

假设您想取消注册上一节中刚刚添加的“间隔符”区块的变体,只需将对应的区块名称和变体名称填入即可。

请在block-variations.js文件的末尾添加以下代码进行测试:

wp.domReady( () => {
	wp.blocks.unregisterBlockVariation( 
		'core/spacer', 
		'themeslug/spacer' 
	);
} );

在取消注册变体时需要注意的一点是,应该将相关操作放在wp.domReady()调用之中。这样做的目的是确保取消注册的操作在加载过程后期、所有变体都已经注册完成之后才执行。