Block Bindings API 仅适用于 WordPress 6.5 及以上版本。

The Block Bindings API 允许您将动态数据“绑定”到块的属性上,这些属性随后会反映在前端输出到浏览器的最终 HTML 标记中。

例如,可以将 Image 块 url 属性连接到返回来自外部 API 的随机图像的功能。

<!-- wp:image {
    "metadata":{
        "bindings":{
            "url":{
                "source":"my-plugin/get-random-images"
            }
        }
    }
} -->

兼容的块及其属性

目前,并非所有块属性都兼容块绑定。正在努力增加这种兼容性,但目前的默认列表如下:

支持的块支持的属性
core/imageid, url, title, alt, caption
core/headingcontent
core/paragraphcontent
core/buttonurl, text, linkTarget, rel
core/navigation-linkurl
core/navigation-submenuurl
core/post-datedatetime

核心源

WordPress 包含几个内置的块绑定源,您可以无需任何自定义注册即可使用:

  • core/post-meta
  • core/post-data
  • core/term-data
  • core/pattern-overrides

core/post-meta

core/post-meta 源允许您将块属性绑定到帖子元数据字段。

要求:

  • 帖子元数据必须使用 show_in_rest => true 进行注册
  • 帖子元数据键不能以下划线开头(受保护的键不可访问)

示例用法:

首先,注册您的帖子元数据:

register_meta(
    'post',
    'my_custom_field',
    array(
        'show_in_rest' => true,
        'single'       => true,
        'type'         => 'string',
    )
);

然后将其绑定到块属性:

<!-- wp:paragraph {
    "metadata":{
        "bindings":{
            "content":{
                "source":"core/post-meta",
                "args":{"key":"my_custom_field"}
            }
        }
    }
} -->
<p>Fallback content</p>
<!-- /wp:paragraph -->

core/post-data

注意:自 WordPress 6.9 起。

core/post-data 源提供对帖子数据字段的访问权限。

可用字段:

  • date – 帖子的发布日期
  • modified – 帖子的最后修改日期
  • link – 帖子的永久链接

示例用法:

<!-- wp:paragraph {
    "metadata":{
        "bindings":{
            "content":{
                "source":"core/post-data",
                "args":{"field":"date"}
            }
        }
    }
} -->
<p>Fallback content</p>
<!-- /wp:paragraph -->

core/term-data

注意:自 WordPress 6.9 起。

core/term-data 源在提供术语上下文时提供对分类法术语数据字段的访问权限。它需要 termId 和 taxonomy 来自块上下文才能正常工作。

可用字段

字段描述示例输出
id术语 ID123
name术语名称Category Name
link到术语归档的 URL`https://example.com/category/news`
slugURL 友好的 slugcategory-slug
description术语描述A description of the category
parent父术语 ID(分层分类法)0
count此术语中的帖子数量5

示例用法

在列表中显示术语名称:

<!-- wp:terms-query {"termQuery":{"taxonomy":"category","perPage":5}} -->
<div class="wp-block-terms-query">
    <!-- wp:term-template {"layout":{"type":"default"}} -->
    <!-- wp:paragraph {"metadata":{"bindings":{"content":{"source":"core/term-data","args":{"field":"name"}}}}} -->
    <p>Category Name</p>
    <!-- /wp:paragraph -->
    <!-- /wp:term-template -->
</div>
<!-- /wp:terms-query -->

创建链接术语归档:

<!-- wp:terms-query {"termQuery":{"taxonomy":"post_tag","perPage":10}} -->
<div class="wp-block-terms-query">
    <!-- wp:term-template {"layout":{"type":"default"}} -->
    <!-- wp:paragraph {"metadata":{"bindings":{"content":{"source":"core/term-data","args":{"field":"name"}}}}} -->
    <p><a href="#">Tag Name</a></p>
    <!-- /wp:paragraph -->
    <!-- /wp:term-template -->
</div>
<!-- /wp:terms-query -->

上下文要求

core/term-data 源在这些上下文中工作:

  1. 任何提供术语上下文的块 – 内置块如 core/term-template,或提供 termId 和 taxonomy 的自定义块通过块上下文
  2. 导航块 – 针对 core/navigation-link 和 core/navigation-submenu 的特殊向后兼容性处理(这些从块属性而不是上下文中读取)

core/pattern-overrides

core/pattern-overrides 源允许模式实例根据其内容进行覆盖。这对于同步模式特别有用,您希望允许特定块进行自定义,同时保持模式的其余部分同步。

工作原理:

  • 模式块可以使用 metadata.bindings 定义哪些属性是可覆盖的
  • 每个模式实例将其覆盖值存储在 content 属性中
  • 绑定使用块的 metadata.name 作为键将块属性连接到覆盖值
  • 上下文结构遵循:pattern/overrides → {block_name} → {attribute_name}

示例用法:

在模式定义中,标记块为可覆盖:

<!-- wp:paragraph {
   "metadata":{
      "bindings":{
         "content":{
            "source":"core/pattern-overrides"
         }
      },
      "name":"custom-heading"
   }
} -->
<p>Default heading text</p>
<!-- /wp:paragraph -->

当模式实例化时,用户可以覆盖该特定实例的内容:

<!-- wp:block {"ref":123,"content":{"custom-heading":{"content":"My custom heading text"}}} / -->

在此示例中:

  • custom-heading 是 core/paragraph 块在 core/pattern-overrides 系统中的唯一标识符。
  • 它在覆盖上下文结构中充当键:pattern/overrides → custom-heading → content。
  • 此标识符允许模式中的多个相同类型的块(例如,core/paragraph)使用 metadata.name 具有不同的、每个实例的属性覆盖。

例如,"custom-heading" 将特定段落块的 content 属性链接到其特定模式实例的覆盖值("My custom heading text")。

扩展支持的属性

注意:自 WordPress 6.9 起。

开发人员可以使用 block_bindings_supported_attributes 过滤器扩展支持的属性列表。此过滤器允许添加对额外块属性的支持。

有两个可用的过滤器:

  • block_bindings_supported_attributes:一个通用过滤器,接收支持的属性数组和块类型名称。
  • block_bindings_supported_attributes_{$block_type}:特定于块类型的动态过滤器(例如,block_bindings_supported_attributes_core/image)。

为 Image 块的 linkDestination 属性添加支持的示例(默认已支持的属性列在上面的兼容块表中):

add_filter(
    'block_bindings_supported_attributes_core/image',
    function ( $supported_attributes ) {
        $supported_attributes[] = 'linkDestination';
        return $supported_attributes;
    }
);

为自定义块添加支持的示例:

add_filter(
    'block_bindings_supported_attributes_my-plugin/my-block',
    function ( $supported_attributes ) {
        $supported_attributes[] = 'title';
        $supported_attributes[] = 'description';
        return $supported_attributes;
    }
);

此过滤器还会影响可用于模式覆盖(Pattern Overrides)的块和属性,因为这两个功能共享相同的底层支持的属性配置。

注册自定义源

注册一个源需要定义至少 name、label 以及一个 callback 函数,该函数从源获取值并将其返回给块属性。

一旦注册了源,任何支持块的 metadata.bindings 属性都可以配置为从该源读取值。

注册可以通过 PHP 在服务器端进行,也可以在编辑器中通过 JavaScript 进行,两者可以共存。

在服务器端注册的标签将被在编辑器中定义的标签覆盖。

服务器端注册

服务器端注册允许应用一个回调函数,该回调函数将在前端为绑定的属性执行。

注册自定义源的函数是 register_block_bindings_source($name, $args):

  • name:设置自定义源唯一 ID 的 string。
  • args:包含以下内容的 array:
    • label:具有自定义源人类可读名称的 string。
    • uses_context:传递给回调函数的块上下文 array(可选)。
    • get_value_callback:将在绑定块的渲染函数中运行的 function。它接受三个参数:source_args、block_instance 和 attribute_name。此值可以通过过滤器 block_bindings_source_value 覆盖。

请注意,register_block_bindings_source() 应该从附加到 init 钩子的处理程序中调用。

这里是一个示例:

add_action(
    'init',
    function () {
        register_block_bindings_source(
            'wpmovies/visualization-date',
            array(
                'label'              => __( 'Visualization Date', 'custom-bindings' ),
                'get_value_callback' => function ( array $source_args, $block_instance ) {
                    $post_id = $block_instance->context['postId'];
                    if ( isset( $source_args['key'] ) ) {
                        return get_post_meta( $post_id, $source_args['key'], true );
                    }
                },
                'uses_context'       => array( 'postId' ),
            )
        );
    }
);

此示例需要注册一个 post_meta,并且,也可以使用过滤器返回默认值 $visualization_date,该值将在下一个标题中显示。

add_action(
    'init',
    function () {
        register_meta(
            'post',
            'wp_movies_visualization_date',
            array(
                'show_in_rest' => true,
                'single'       => true,
                'type'         => 'string',
                'label'        => __( 'Movie visualization date', 'custom-bindings' ),
            )
        );
    }
);
注意:以下划线开头的 Post meta 键(例如 `_example_key`)是受保护的,不能用于块绑定。此外,Post meta 必须使用 `show_in_rest = true` 注册,才能通过块绑定 API 可用。

块绑定源值过滤器

注意:自 WordPress 6.7 起。

get_value_callback 返回的值可以通过 block_bindings_source_value 过滤器进行修改。
该过滤器具有以下参数:

  • value:要过滤的值。
  • name:源的名称。
  • source_args:包含源参数的 array。
  • block_instance:块实例对象。
  • attribute_name:属性的名称。

示例:

function wpmovies_format_visualization_date( $value, $name ) {
    // Prevent the filter to be applied to other sources.
    if ( $name !== 'wpmovies/visualization-date' ) {
        return $value;
    }
    if ( ! $value ) {
        return date( 'm/d/Y' );
    }
    return date( 'm/d/Y', strtotime( $value ) );
}

add_filter( 'block_bindings_source_value', 'wpmovies_format_visualization_date', 10, 2 );

服务器端注册核心示例

有一些核心示例可以用作参考。

编辑器注册

注意:自 WordPress 6.7 起。

客户端上的编辑器注册允许定义当获取值或编辑值时,绑定的块将执行的操作。

注册自定义源的函数是 registerBlockBindingsSource( args ):

  • args:具有以下结构的 object:
    • name:具有唯一且机器可读名称的 string。
    • label:具有自定义源人类可读名称的 string。如果已在服务器端定义,则服务器标签将被此标签覆盖,在这种情况下,不建议在此处定义它。(可选)
    • usesContext:自定义源可能需要块上下文的 array。如果已在服务器端定义,则不应在此处定义它。(可选)
    • getValues:从源检索值的 function。(可选)
    • setValues:允许更新连接到源的值的 function。(可选)
    • canUserEditValue:确定用户是否可以编辑值的 function。默认情况下,用户无法编辑它。(可选)
    • getFieldsList:返回 UI 下拉选择器可用字段的 function。(自 WordPress 6.9 起)(可选)

此示例将在编辑器中显示自定义 Post meta 日期,如果不存在,则显示今天的日期。用户可以编辑日期的值。(注意:此示例不对用户输入进行日期格式化——仅用于教学目的。)

import { registerBlockBindingsSource } from '@wordpress/blocks';
import { __ } from '@wordpress/i18n';
import { store as coreDataStore } from '@wordpress/core-data';

registerBlockBindingsSource( {
    name: 'wpmovies/visualization-date',
    label: __( 'Visualization Date', 'custom-bindings' ), // We can skip the label, as it was already defined in the server in the previous example.
    usesContext: [ 'postType' ], // We can skip postId, as it was already defined in the server in the previous example.
    getValues( { select, context } ) {
        let wpMoviesVisualizationDate;
        const { getEditedEntityRecord } = select( coreDataStore );
        if ( context?.postType && context?.postId ) {
            wpMoviesVisualizationDate = getEditedEntityRecord(
                'postType',
                context?.postType,
                context?.postId
            ).meta?.wp_movies_visualization_date;
        }
        if ( wpMoviesVisualizationDate ) {
            return {
                content: wpMoviesVisualizationDate,
            };
        }

        return {
            content: new Date().toLocaleDateString( 'en-US' ),
        };
    },
    setValues( { select, dispatch, context, bindings } ) {
        dispatch( coreDataStore ).editEntityRecord(
            'postType',
            context?.postType,
            context?.postId,
            {
                meta: {
                    wp_movies_visualization_date: bindings?.content?.newValue,
                },
            }
        );
    },
    canUserEditValue( { select, context } ) {
        return true;
    },
} );

getValues

getValues 函数在块加载时从源检索值。它接收一个 object 作为参数,具有以下属性:

  • bindings 返回特定源的绑定对象。它必须以属性为键,值可以是 string 或具有参数的 object。
  • clientId 返回当前块客户端 ID 的 string。
  • context 返回一个当前块上下文的 object 对象,该上下文定义在 usesContext 属性中。关于块上下文的更多信息。
  • select 返回给定 store 的选择器 object。在它们的文档中查看更多信息。

该函数必须返回一个具有此结构的 object:
{ '块属性' : 值 }

setValues

setValues 函数更新绑定块的源的所有值。它接收一个 object 作为参数,具有以下属性:

getFieldsList

注意:自 WordPress 6.9 起。

getFieldsList 函数使自定义源能够出现在块绑定 UI 下拉选择器中。当用户从下拉列表中选择选项时,源会自动与所选字段对应的 args 绑定的块属性进行绑定。该函数必须返回一个定义可用绑定选项的字段对象数组。

数组中的每个字段对象应具有以下属性:

  • label:定义在下拉选择器中显示的标签的 string。如果未提供,则默认为源标签。
  • type:定义属性值类型的 string。它必须与它绑定的属性类型匹配;否则,它不会出现在 UI 中。例如,只接受数字的 id 属性应仅显示返回数值值的字段。
  • args:定义当用户从下拉列表中选择字段时应用的源参数的 object。

示例:

registerBlockBindingsSource( {
    name: 'my-plugin/custom-fields',
    label: 'Custom Fields',
    getFieldsList() {
        return [
            {
                label: 'Author Name',
                type: 'string',
                args: {
                    field: 'author_name',
                },
            },
            {
                label: 'Publication Year',
                type: 'string',
                args: {
                    field: 'publication_year',
                },
            },
            {
                label: 'Page Count',
                type: 'number',
                args: {
                    field: 'page_count',
                },
            },
        ];
    },
    getValues( { bindings } ) {
        // Implementation to retrieve values based on args.field
    },
} );

通过此实现,当将块属性绑定到您的自定义源时,用户将在块绑定 UI 下拉列表中看到“作者姓名”、“出版年份”和“页数”作为选项。

查看 Editor Bindings 示例,来自 Block Development Examples 存储库

编辑器注册核心示例

Core 中有几个示例可用作参考。

注销源

注意:自 WordPress 6.7 起。

unregisterBlockBindingsSource 通过提供其名称来注销块绑定源。

import { unregisterBlockBindingsSource } from '@wordpress/blocks';

unregisterBlockBindingsSource( 'plugin/my-custom-source' );

获取所有源

注意:自 WordPress 6.7 起。

getBlockBindingsSources 返回所有已注册的块绑定源。

import { getBlockBindingsSources } from '@wordpress/blocks';

const registeredSources = getBlockBindingsSources();

获取特定源

注意:自 WordPress 6.7 起。

getBlockBindingsSource 通过其名称返回特定的块绑定源。

import { getBlockBindingsSource } from '@wordpress/blocks';

const blockBindingsSource = getBlockBindingsSource( 'plugin/my-custom-source' );

块绑定工具

注意:自 WordPress 6.7 起。

UseBlockBindingUtils 是一个具有两个辅助函数的钩子,允许开发人员轻松编辑 metadata.bindings 属性。

它接受一个 clientId 字符串作为参数,如果未设置,则函数将从上下文中使用当前块客户端 ID。

示例:

import { useBlockBindingsUtils } from '@wordpress/block-editor';

const { updateBlockBindings } = useBlockBindingsUtils('my-block-client-id-12345');
...

updateBlockBindings

updateBlockBindings 的工作方式类似于 updateBlockAttributes,可用于创建、更新或删除特定连接。

import { useBlockBindingsUtils } from '@wordpress/block-editor';

const { updateBlockBindings } = useBlockBindingsUtils();

function updateBlockBindingsURLSource( url ) {
    updateBlockBindings( {
        url: {
            source: 'myplugin/new-source',
        },
    } );
}

// Remove binding from url attribute.
function removeBlockBindingsURLSource() {
    updateBlockBindings( { url: undefined } );
}

removeAllBlockBindings

removeAllBlockBindings 将通过删除 metadata.bindings 属性来删除块中的所有现有连接。

import { useBlockBindingsUtils } from '@wordpress/block-editor';

const { removeAllBlockBindings } = useBlockBindingsUtils();

function clearBlockBindings() {
    removeAllBlockBindings();
}