Gutenberg 区块编辑器文档

title: "绑定" post_status: publish comment_status: open taxonomy: category: - gutenberg-docs post_tag: - Block Api - Reference Guides - Repos


绑定

区块绑定 API 仅适用于 WordPress 6.5 及以上版本。

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

例如,可以将图像区块的 url 属性连接到一个函数,该函数从外部 API 返回随机图像。

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

Compatible blocks and their attributes

Right now, not all block attributes are compatible with block bindings. There is some ongoing effort to increase this compatibility, but for now, this is the default list:

Supported Blocks Supported Attributes
core/image id, url, title, alt, caption
core/heading content
core/paragraph content
core/button url, text, linkTarget, rel
core/navigation-link url
core/navigation-submenu url
core/post-date datetime

核心数据源

WordPress 内置了多个区块绑定数据源,无需自定义注册即可使用:

core/post-meta

core/post-meta 源允许你将区块属性绑定到文章元字段。

要求:

使用示例:

首先,注册你的文章元:

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>回退内容</p>
<!-- /wp:paragraph -->

core/post-data

注意: 自 WordPress 6.9 起。

core/post-data 数据源提供对文章数据字段的访问。

可用字段:

使用示例:

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

core/term-data

注意: 自 WordPress 6.9 起。

当存在分类术语上下文时,core/term-data 数据源提供对分类术语数据字段的访问。它需要从区块上下文中获取 termIdtaxonomy 才能正常工作。

Available Fields

Field Description Example Output
id Term ID 123
name Term name Category Name
link URL to term archive https://example.com/category/news
slug URL-friendly slug category-slug
description Term description A description of the category
parent Parent term ID (hierarchical taxonomies) 0
count Number of posts in this term 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>分类名称</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="#">标签名称</a></p>
    <!-- /wp:paragraph -->
    <!-- /wp:term-template -->
</div>
<!-- /wp:terms-query -->

上下文要求

core/term-data 源文件在以下上下文中工作:

  1. 任何提供术语上下文的区块 - 内置区块如 core/term-template,或通过区块上下文提供 termIdtaxonomy 的自定义区块
  2. 导航区块 - 为 core/navigation-linkcore/navigation-submenu 提供特殊的向后兼容处理(这些区块从区块属性而非上下文中读取数据)

core/pattern-overrides

The core/pattern-overrides source enables pattern instances to have their content overridden on a per-instance basis. This is particularly useful for synced patterns where you want to allow specific blocks to be customized while keeping the rest of the pattern synchronized .

How it works:

Example usage:

In the pattern definition, mark blocks as overridable:

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

When the pattern is instantiated, users can override the content for that specific instance:

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

In this example:

For instance, "custom-heading" links the specific paragraph block's content attribute to its override value ("My custom heading text") for a particular pattern instance.

扩展支持的属性

注意: 自 WordPress 6.9 起。

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

有两个可用的过滤器:

为 Image 块添加 caption 属性支持的示例:

add_filter(
    'block_bindings_supported_attributes_core/image',
    function ( $supported_attributes ) {
        $supported_attributes[] = 'caption';
        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;
    }
);

此过滤器也会影响哪些块和属性可用于模式覆盖,因为这两个功能共享相同的基础支持属性配置。

注册自定义数据源

注册数据源需要至少定义 namelabel 以及一个 callback 函数,该函数从数据源获取值并传递给区块属性。

数据源注册后,任何支持区块的 metadata.bindings 属性均可配置为从该数据源读取值。

注册可通过 PHP 在服务器端完成,或通过 JavaScript 在编辑器内完成,两种方式可共存。

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

Server registration

Server registration allows applying a callback that will be executed on the frontend for the bound attribute.

The function to register a custom source is register_block_bindings_source($name, $args):

Note that register_block_bindings_source() should be called from a handler attached to the init hook.

Here is an example:

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

This example needs a post_meta registered, and, also, a filter can be used to return a default $visualization_date value, which will be shown in the next heading.

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' ),
            )
        );
    }
);
Note: Post meta keys that begin with an underscore (e.g. `_example_key`) are protected and cannot be used with Block Bindings. Additionally, post meta must be registered with `show_in_rest = true` to be available through the Block Bindings API.

Block bindings source value filter

Note: Since WordPress 6.7.

The value returned by get_value_callback can be modified with the block_bindings_source_value filter. The filter has the following parameters:

Example:

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

服务器注册核心示例

Core 中有几个示例可供参考。

Editor registration

Note: Since WordPress 6.7.

Editor registration on the client allows defining what the bound block will do when the value is retrieved or when the value is edited.

The function to register a custom source is registerBlockBindingsSource( args ):

This example will show a custom post meta date in the editor and, if it doesn't exist, it will show today's date. The user can edit the value of the date. (Caution: This example does not format the user input as a date—it's only for educational purposes.)

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

The getValues function retrieves the value from the source on block loading. It receives an object as an argument with the following properties:

The function must return an object with this structure: { 'block attribute' : value }

setValues

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

getFieldsList

Note: Since WordPress 6.9.

The getFieldsList function enables custom sources to appear in the Block Bindings UI dropdown selector. When a user selects an option from the dropdown, the source is automatically bound to the block attribute with the corresponding args from the selected field. This function must return an array of field objects that define the available binding options.

Each field object in the array should have the following properties:

Example:

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
    },
} );

With this implementation, users will see "Author Name", "Publication Year", and "Page Count" as options in the Block Bindings UI dropdown when binding block attributes to your custom source.

Check the Editor Bindings example from the Block Development Examples repo

编辑器注册核心示例

核心中有几个示例可供参考。

注销数据源

注意: 自 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',
        },
    } );
}

// 从 url 属性中移除绑定。
function removeBlockBindingsURLSource() {
    updateBlockBindings( { url: undefined } );
}

removeAllBlockBindings

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

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

const { removeAllBlockBindings } = useBlockBindingsUtils();

function clearBlockBindings() {
    removeAllBlockBindings();
}