社区新闻

如何使用 PHP 注册区块变体

查看官方原文 ↗ 发布于

WordPress 即将推出一种注册自定义区块变体的新方法。过去,您通常需要通过基于 JavaScript 的 Variations API 来注册它们,但在 WordPress 6.5 中,您将能够使用一个专用的 PHP 过滤器钩子来定义变体。

此钩子的添加是一个更大、专注于性能的补丁的一部分,您可以在开发说明中了解更多信息。对于插件和主题作者来说,好处在于它使注册变体的过程变得更加容易。

这一变化也为那些不太熟悉 JavaScript 的开发者提供了更多与区块系统集成的机会。那么,让我们深入了解在 WordPress 6.5 中可以实现哪些功能。

如果您不熟悉区块变体,请查看开发者博客上的区块变体介绍

从技术上讲,长期以来都可以通过 PHP 添加变体,即通过 register_block_type_args 过滤器钩子注入它们,但这种方法没有文档记录,也没有向开发者明确说明。WordPress 6.5 中的新方法还限制了您过滤的范围,因为它专门针对区块变体,而不是整个区块。

区块变体钩子与回调

从技术上讲,WordPress 6.5 并没有创建一套标准的 API 函数来注册变体。但它确实添加了一个名为 get_block_type_variations 的新过滤器钩子,允许您从插件或主题注入自定义变体。

看一下 get_block_type_variations 过滤器钩子:

apply_filters(
	'get_block_type_variations',
	array $variations,
	WP_Block_Type $block_type
);

如上所示,该钩子最多可以向应用于它的任何过滤器传递两个参数:

  • $variations 特定区块已注册变体的数组。
  • $block_type WP_Block_Type 类的实例,代表一个已注册的区块类型。

在为该钩子定义过滤器时,您几乎总是需要这两个参数。因此,在调用 add_filter() 函数时,请务必将 $accepted_args 参数设置为 2

以下是一个虚构的 get_block_type_variations 过滤器示例,以帮助您熟悉其格式:

add_filter( 'get_block_type_variations', 'themeslug_block_type_variations', 10, 2 );

function themeslug_block_type_variations( $variations, $block_type ) {

	if ( 'namespace/block-a' === $block_type->name ) {
		// 向 `$variations` 数组添加变体。
	} elseif ( 'namespace/block-b' === $block_type->name ) {
		// 向 `$variations` 数组添加更多变体。
	}

	return $variations;
}

始终需要运行一个 if 条件检查,以确定该区块是否是您要为其定义变体的那个。您可以使用 $block 参数的 name 属性来实现这一点。

您的过滤器函数还可以为单个区块添加多个变体,或者通过将变体附加到 $variations 参数来为多个区块定义变体。

构建自定义变体

现在到了有趣的部分:注册一个自定义区块变体!

在这个例子中,让我们使用 PHP 来重新创建 Variations API 区块编辑器手册文档中的一个基于 JavaScript 的示例。该变体只做了一个属性更改:将“媒体与文本”区块的媒体部分移动到右侧。

当插入到区块编辑器时,该变体将如下所示:

WordPress 文章编辑器,内容区域有一个单独的“媒体与文本”区块。媒体上传字段右对齐,内容在左侧。

要创建此变体,您需要做的第一件事是在 get_block_type_variations 上添加一个过滤器。因为您知道要定位的区块类型(媒体与文本),所以请继续添加一个检查,将以下代码添加到您主题的 functions.php 或插件文件中:

add_filter( 'get_block_type_variations', 'themeslug_block_type_variations', 10, 2 );

function themeslug_block_type_variations( $variations, $block_type ) {

	if ( 'core/media-text' === $block_type->name ) {
		// 在此处添加您的变体。
	}

	return $variations;
}

现在您必须决定哪些属性使此变体与默认区块不同。对于“媒体与文本”区块,您可以通过其 block.json 文件找到其可用属性。在本例中,您将把 mediaPosition 属性设置为 right(其默认值为 left)。

您可以为变体设置其他几个参数,我们稍后会讲到。现在,更新您的 themeslug_block_type_variations() 函数,使其如下所示:

add_filter( 'get_block_type_variations', 'themeslug_block_type_variations', 10, 2 );

function themeslug_block_type_variations( $variations, $block_type ) {

	if ( 'core/media-text' === $block_type->name ) {
		$variations[] = array(
			'name'       => 'themeslug-media-right',
			'title'      => __( 'Media & Text: Right', 'themeslug' ),
			'isActive'   => array(
				'mediaPosition' 
			),
			'attributes' => array(
				'mediaPosition' => 'right'
			)
		);
	}

	return $variations;
}

请注意此变体设置的参数:nametitleisActiveattributes。这四个参数我认为是几乎所有变体的“必备”参数。

这是一个相对基础的示例,说明了基于 PHP 的变体如何工作,您当然可以为您的项目构建更复杂的变体。除了本教程之外,一个好的练习是通读使用查询循环区块变体构建书评网格并将代码转换为 PHP。

自定义变体参数

我不会深入探讨注册自定义区块变体的各种参数。这些在 Variations 手册文档中有详细记录。但我想列出每个参数的基本定义,并注意使用 PHP 和 JavaScript 之间的差异。

您可以为您的变体定义以下任何参数:

  • name 变体的唯一标识符。最佳实践是使用您的主题/插件 slug 作为前缀。
  • title 可选的人类可读标题,应进行国际化。
  • description 变体的描述,应进行国际化。
  • category 如果与区块本身不同,用于放置变体的区块类别。
  • keywords 帮助用户在搜索时发现变体的术语数组。
  • icon 一个 Dashicon 字符串,代表您想要显示的图标。与基于 JavaScript 的变体不同,您不能分配自定义 SVG。
  • attributes 定义您的变体与默认值不同的属性数组。
  • innerBlocks 嵌套区块的初始配置(如果区块允许嵌套区块)。
  • example 用于区块预览的结构化数据数组。
  • scope 变体适用范围的数组,包括 blockinsertertransform
  • isDefault 该变体是否应为默认值。
  • isActive 应用于确定变体是否处于活动状态的区块属性数组。与 JavaScript 注册的变体不同,您不能传递用于确定活动状态的自定义回调函数。

需要重申上述列表中 JavaScript 和 PHP 注册之间的两个主要区别。首先,您不能使用自定义 icon,仅限于可用的 Dashicons。

但最大的限制可能在于 isActive 参数。对于简单的变体,传递一个要检查的属性数组应该没问题。但对于需要自定义回调来确定活动状态的更复杂变体,最好使用 JavaScript。

除了这些限制之外,使用 PHP 的区块变体参数与使用 JavaScript 时的工作方式完全相同。

未来的 API?

目前有一个开放工单,提议添加一个标准的 register_block_variation() PHP 函数,这将是 registerBlockVariation() JavaScript 函数的等效物。此工单尚未关联拉取请求,因此任何人都可以接手,如果他们希望将此函数包含在核心中。

在此之前,get_block_type_variations 过滤器钩子始终可用。