WordPress 6.4 引入了区块钩子(Block Hooks) ( #53987 ),该功能为块主题提供了可扩展性机制。这是模拟 WordPress 的Hooks概念的第一步, 该概念允许开发人员使用过滤器和操作来扩展经典主题。
具体来说,Block Hooks API允许块相对于其他块类型的实例自动插入自身。例如,“喜欢”按钮块可以要求插入到帖子内容块之前,或者电子商务购物车块可以要求插入到导航块之后。
原则和当前限制
Block Hooks有两个核心原则:
- 一旦包含挂钩块的插件被激活,前端插入就应该发生。换句话说,用户不需要在编辑器中手动插入块。同样,禁用插件应该从前端删除挂钩块。
- 用户对任何自动插入的块拥有最终控制权。这意味着挂钩的块在编辑器中可见,并且用户保留、删除、自定义或移动该块的决定将受到尊重并反映在前端。
为了兼顾这两个原则,必须进行权衡。块挂钩仅限于模板、模板部分和样板(即定义主题布局的元素)。对于样板(patterns),这包括由主题、来自 Block Pattern Directory或对 register_block_pattern
的调用提供的样板。
区块无法挂钩到用户制作的帖子内容或样板,例如同步样板或用户已修改的主题模板和模板部分。
此外,从 WordPress 6.4 开始,您无法自动插入具有保存功能的块,否则会出现块验证错误。用通俗的话说,这意味着块钩子与动态块一起工作,而不是静态块。关于两者的区别可以参考这篇文章。
使用区块钩子
您可以通过两种不同的方式实现块钩子:在块的block.json
文件中或使用新的hooked_block_types
过滤器。虽然更简单,但该block.json
方法提供了更有限的实现,因此让我们首先回顾一下。
block.json
这种block.json
方法允许您无条件地挂载第三方块,这意味着在上述限制的情况下,该块将相对于目标(锚点)块的所有实例插入。
在块的block.json
文件中,包含该blockHooks
属性。此属性采用一个对象,其中键 ( string
) 是要挂载的块的名称,值 ( string
) 指定其位置。可能的位置有:
before
– 在目标块之前注入。after
– 在目标块之后注入。firstChild
– 在目标容器块的第一个内部块之前注入。lastChild
– 在目标容器块的最后一个内部块之后注入。
{
blockHooks: {
'core/verse': 'before'
'core/spacer': 'after',
'core/column': 'firstChild',
'core/comment-template': 'lastChild',
}
}
在上面的示例中,该块将插入到出现在未修改的模板、模板部分或样板中的每个 Verse 块之前。它还将被插入到每个 Spacer 块之后,等等。
当使用 firstChild
或 lastChild
的block.json
方法时,标题为“插件”的设置侧边栏面板将被添加到编辑器中的目标块中。这允许用户打开和关闭挂钩块。
下面是一个链接到“评论模板”块中的 lastChild
位置的“赞”按钮块的示例。
hooked_block_types
hooked_block_types
过滤器提供了更大的灵活性。它允许您像 block.json
方法一样无条件地挂钩任何动态块,或者根据目标(锚点)块所在的模板、模板部分或样板有条件地挂钩。
过滤器的回调函数接受四个参数:
$hooked_blocks
(array) – 钩子块的数组。$position
(string) – 挂载的块的相对位置:before
、after
、first_child
、 或last_child
。$anchor_block
(字符串) – 锚块的名称。$context
(WP_Block_Template|array) – 锚块所属的块模板、模板部分或样板。
下面是一些使用Like 按钮块插件 ( ockham/like-button
) 的示例,旨在演示第三方块中的区块钩子功能。该样板示例确实需要2024主题。
function example_block_hooks( $hooked_blocks, $position, $anchor_block, $context ) {
// Template/Template Part hooks.
if ( $context instanceof WP_Block_Template ) {
// Hooks the "Like" button block before the Post Title in the Single template.
if (
'core/post-title' === $anchor_block &&
'before' === $position &&
'single' === $context->slug
) {
$hooked_blocks[] = 'ockham/like-button';
}
// Hooks the Login/Logout link block after the Navigation block if the context of the template part is a header.
if (
'core/group' === $anchor_block &&
'last_child' === $position &&
'header' === $context->area
) {
$hooked_blocks[] = 'core/loginout';
}
}
// Pattern hooks.
if ( is_array( $context ) && isset( $context['slug'] ) ) {
// Hooks into the Post Meta pattern in the Twenty Twenty-Four theme.
if (
'core/post-terms' === $anchor_block &&
'after' === $position &&
'twentytwentyfour/post-meta' === $context['slug']
) {
$hooked_blocks[] = 'ockham/like-button';
}
}
return $hooked_blocks;
}
add_filter( 'hooked_block_types', 'example_block_hooks', 10, 4 );
值得注意的是,$context
将是 WP_Block_Template
模板和模板部件的 object
类型以及样板的 array
类型。如果要使用此参数有条件地插入块,请确保在应用挂钩块之前检查参数类型。
您还会注意到,您只能指定正在挂钩的块的名称。无法设置挂钩块的属性,因此仅插入块的默认实例。区块钩子的未来改进可能会解决此限制和其他限制,为开发人员扩展块主题提供可靠的方法。
有关当前正在开发哪些附加功能的更多信息,请继续关注区块钩子改进的跟踪问题。