Gutenberg 区块编辑器文档

title: "Metadata in block.json" post_status: publish comment_status: open taxonomy: category: - gutenberg-docs post_tag: - Block Api - Reference Guides - Repos


Metadata in block.json

Starting with the WordPress 5.8 release, we recommend using the block.json metadata file as the canonical way to register block types with both PHP (server-side) and JavaScript (client-side). Here is an example block.json file that would define the metadata for a plugin create a notice block.

Example:

{
    "$schema": "https://schemas.wp.org/trunk/block.json",
    "apiVersion": 3,
    "name": "my-plugin/notice",
    "title": "Notice",
    "category": "text",
    "parent": [ "core/group" ],
    "icon": "star",
    "description": "Shows warning, error or success notices...",
    "keywords": [ "alert", "message" ],
    "version": "1.0.3",
    "textdomain": "my-plugin",
    "attributes": {
        "message": {
            "type": "string",
            "source": "html",
            "selector": ".message"
        }
    },
    "providesContext": {
        "my-plugin/message": "message"
    },
    "usesContext": [ "groupId" ],
    "selectors": {
        "root": ".wp-block-my-plugin-notice"
    },
    "supports": {
        "align": true
    },
    "styles": [
        { "name": "default", "label": "Default", "isDefault": true },
        { "name": "other", "label": "Other" }
    ],
    "example": {
        "attributes": {
            "message": "This is a notice!"
        }
    },
    "variations": [
        {
            "name": "example",
            "title": "Example",
            "attributes": {
                "message": "This is an example!"
            }
        }
    ],
    "editorScript": "file:./index.js",
    "script": "file:./script.js",
    "viewScript": [ "file:./view.js", "example-shared-view-script" ],
    "editorStyle": "file:./index.css",
    "style": [ "file:./style.css", "example-shared-style" ],
    "viewStyle": [ "file:./view.css", "example-view-style" ],
    "render": "file:./render.php"
}

使用元数据文件的优势

区块定义允许在 JavaScript、PHP 和其他语言之间共享处理存储为 JSON 的区块类型的代码,而使用 block.json 元数据文件注册区块在此基础上还提供了多重优势。

从性能角度来看,当主题支持资源懒加载时,通过 block.json 注册的区块将自动获得优化的资源入队机制。在 stylescript 属性中列出的前端 CSS 和 JavaScript 资源仅在页面上存在该区块时才会入队,从而有效减小页面体积。

此外,由于区块类型 REST API 端点仅能列出在服务器端注册的区块,因此建议在服务器端注册区块;使用 block.json 文件可以简化这一注册流程。

WordPress 插件目录能够检测 block.json 文件,高亮显示插件中包含的区块,并提取其元数据。若希望将区块提交至区块目录,插件中包含的所有区块都必须具备 block.json 文件,以便区块目录识别它们。

通过使用已定义的架构定义文件可改善开发体验。支持的编辑器能够提供工具提示、自动补全和架构验证等辅助功能。要使用此架构,请在 block.json 文件顶部添加以下内容:

"$schema": "https://schemas.wp.org/trunk/block.json"
请查阅区块注册指南,深入了解如何使用元数据注册区块。

区块 API

本节描述所有可添加到 block.json 文件中的属性,用于定义区块类型的行为和元数据。

API 版本

{ "apiVersion": 3 }

区块所使用的 Block API 版本。最新版本为 3,于 WordPress 6.3 中引入。

更多详情请参阅 API 版本文档

名称

{ "name": "core/heading" }

区块名称是标识区块的唯一字符串。名称必须遵循 命名空间/区块名称 的结构,其中命名空间是您的插件或主题的名称。

注意: 区块名称只能包含小写字母数字字符、连字符,并且最多只能有一个正斜杠用于指定插件唯一的命名空间前缀。它必须以字母开头。

注意: 此名称在注释分隔符中使用,格式为 <!-- wp:my-plugin/book -->core 命名空间中的区块类型在序列化时不包含命名空间。

Title

{ "title": "Heading" }

This is the display title for your block, which can be translated with our translation functions. The title will display in the Inserter and in other areas of the editor.

Note: To keep your block titles readable and accessible in the UI, try to avoid very long titles.

分类

{ "category": "text" }

区块被分组到不同类别中,以帮助用户浏览和发现它们。

核心提供的类别有:

插件和主题也可以注册自定义区块类别

实现时应预期并容忍未知的类别,并提供一些合理的回退行为(例如,归入 "text" 类别)。

父级

{ "parent": [ "my-block/product" ] }

设置 parent 可以让一个区块要求其仅在嵌套于指定区块内时才可用。例如,您可能希望只允许“加入购物车”区块在“产品”区块内可用。

祖先

{ "ancestor": [ "my-block/product" ] }

ancestor 属性使一个块可以在指定块类型的祖先块子树中的任何位置使用。例如,只要 'Column' 块位于 'Comment Template' 块内的某处,就允许将 'Comment Content' 块放置在 'Column' 块内。与 parent 属性相比,指定了 ancestor 的块可以放置在子树中的任何位置,而指定了 parent 的块必须是直接子级。

允许的区块

{ "allowedBlocks": [ "my-block/product" ] }

allowedBlocks 指定了哪些区块类型可以作为该区块的直接子级。例如,一个‘列表’区块可以只允许‘列表项’区块作为其子级。

图标

{ "icon": "smile" }

应指定一个图标属性,以便更轻松地识别区块。这些图标可以是 WordPress 的 Dashicons 中的任意一个(其 slug 在非 JS 环境中也可作为备用方案)。

注意: 也可以在客户端使用 SVG 元素的源来覆盖此属性。此外,此属性可以通过 JavaScript 定义为一个包含背景色和前景色的对象。这些颜色在适用时会与图标一起显示,例如:在插入器中。自定义 SVG 图标会自动包装在 wp.primitives.SVG 组件中,以添加可访问性属性(aria-hidden、role 和 focusable)。

Description

{
    "description": "Introduce new sections and organize content to help visitors"
}

This is a short description for your block, which can be translated with our translation functions. This will be shown in the block inspector.

关键词

{ "keywords": [ "keyword1", "keyword2" ] }

有时,一个区块可以拥有别名,以帮助用户在搜索时发现它。例如,一个图片区块可能也希望用户通过搜索“照片”找到它。您可以通过提供一个不限长度的术语数组(这些术语会被翻译)来实现此目的。

版本

{ "version": "1.0.3" }

区块的当前版本号,例如 1.0 或 1.0.3。其版本控制方式类似于插件。此字段可能与区块资源一起使用以控制缓存失效,当区块作者省略此字段时,则使用已安装的 WordPress 版本。

文本域

{ "textdomain": "my-plugin" }

插件/区块的 gettext 文本域。更多信息可在 如何国际化你的插件 页面的 文本域 部分找到。

属性

{
    "attributes": {
        "cover": {
            "type": "string",
            "source": "attribute",
            "selector": "img",
            "attribute": "src"
        },
        "author": {
            "type": "string",
            "source": "html",
            "selector": ".book-author"
        }
    }
}

属性提供了区块所需的结构化数据。它们在序列化时可能以不同形式存在,但都在一个公共接口下声明。

更多详情请参阅属性文档

提供上下文

以对象形式提供上下文,供此类型块的后代块访问。该对象将上下文名称映射到块自身的某个属性。

更多详情请参阅 块上下文文档

{
    "providesContext": {
        "my-plugin/recordId": "recordId"
    }
}

上下文

要从祖先提供者继承的上下文值名称数组。

更多详情请参阅 区块上下文文档

{
    "usesContext": [ "message" ]
}

选择器

用于在为主题.json(全局样式)样式表生成块样式时使用的任何自定义 CSS 选择器,以 root、特性或子特性为键。提供自定义选择器可以更精细地控制哪些样式应用于哪些块元素,例如,仅将排版样式应用于内部标题,而颜色仍应用于外部块包装器等。

更多详情请参阅选择器文档

{
    "selectors": {
        "root": ".my-custom-block-selector",
        "color": {
            "text": ".my-custom-block-selector p"
        },
        "typography": {
            "root": ".my-custom-block-selector > h2",
            "text-decoration": ".my-custom-block-selector > h2 span"
        }
    }
}

支持功能

它包含一组用于控制编辑器中功能的选项。更多详情请参阅支持功能文档

Block Styles

{
    "styles": [
        { "name": "default", "label": "Default", "isDefault": true },
        { "name": "other", "label": "Other" }
    ]
}

Block styles can be used to provide alternative styles to block. It works by adding a class name to the block's wrapper. Using CSS, a theme developer can target the class name for the block style if it is selected.

Plugins and Themes can also register custom block styles for existing blocks.

示例

{
    "example": {
        "attributes": {
            "message": "This is a notice!"
        }
    }
}

它为区块提供结构化的示例数据。此数据用于构建区块预览,当用户将鼠标悬停在区块上时,该预览会显示在检查器帮助面板中。

更多详情请参阅 示例文档

Variations

{
    "variations": [
        {
            "name": "example",
            "title": "Example",
            "attributes": {
                "level": 2,
                "message": "This is an example!"
            },
            "scope": [ "block" ],
            "isActive": [ "level" ]
        }
    ]
}

Block Variations is the API that allows a block to have similar versions of it, but all these versions share some common functionality. Each block variation is differentiated from the others by setting some initial attributes or inner blocks. Then at the time when a block is inserted these attributes and/or inner blocks are applied.

Note: In JavaScript you can provide a function for the isActive property, and a React element for the icon. In the block.json file both only support strings

Starting with version 6.7, it is possible to specify a PHP file in block.json that generates the list of block variations on the server side:

{ "variations": "file:./variations.php" }

That PHP file is expected to return an array that contains the block variations. Strings found in the variations returned from the PHP file will not be localized automatically; instead, use the __() function as usual.

For example:

<?php
// Generate variations for a Social Icon kind of block.

return array(
    array(
        'isDefault'  => true,
        'name'       => 'wordpress',
        'title'      => 'WordPress',
        'icon'       => 'wordpress',
        'attributes' => array(
            'service' => 'wordpress',
        ),
        'isActive'   => array( 'service' )
    ),
    array(
        'name'       => 'mail',
        'title'      => __( 'Mail' ),
        'keywords'   => array(
            __( 'email' ),
            __( 'e-mail' )
        ),
        'icon'       => 'mail',
        'attributes' => array(
            'service' => 'mail',
        ),
        'isActive'   => array( 'mail' )
    ),
);

See the variations documentation for more details.

区块钩子

{
    "blockHooks": {
        "my-plugin/banner": "after"
    }
}

区块钩子是一个 API,它允许一个区块根据“被钩入”区块指定的相对位置,自动插入到给定区块类型的所有实例旁边。也就是说,一个区块可以选择插入到给定区块类型之前或之后,或者作为其第一个或最后一个子元素(即分别添加到其子区块列表的开头或末尾)。被钩入的区块将同时出现在前端和编辑器中(以允许用户进行自定义)。

键是要钩入的区块名称(string),值是要钩入的位置(string)。请查看区块钩子文档以获取有关可用配置的更多信息。

编辑器脚本

{ "editorScript": "file:./index.js" }

区块类型的编辑器脚本定义。这些脚本仅在编辑器上下文中被加入队列。

可以传递一个通过 wp_register_script 函数注册的脚本句柄、一个相对于 block.json 文件的 JavaScript 文件路径,或者一个包含两者混合的列表 (了解更多)。

注意:从 WordPress 6.1.0 版本开始,也支持传递一个编辑器脚本数组。

脚本

{ "script": "file:./script.js" }

定义区块类型的前端和编辑器脚本。这些脚本将在编辑器中和在网站前端查看内容时同时入队。

可以传递一个通过 wp_register_script 函数注册的脚本句柄、一个相对于 block.json 文件的 JavaScript 文件路径,或者一个包含两者混合的列表 (了解更多)。

注意:从 WordPress 6.1.0 版本开始,也支持传递脚本数组。

视图脚本

{ "viewScript": [ "file:./view.js", "example-shared-view-script" ] }

区块类型前端脚本定义。这些脚本仅在网站前端查看内容时才会入队。

可以传递一个通过 wp_register_script 函数注册的脚本句柄、一个相对于 block.json 文件的 JavaScript 文件路径,或者一个包含两者混合的列表 (了解更多)。

注意:自 WordPress 6.1.0 起,也支持传递一个视图脚本数组。

视图脚本模块

{ "viewScriptModule": [ "file:./view.js", "example-shared-script-module-id" ] }

区块类型的前端脚本模块定义。它们仅在网站前端查看内容时才会被加入队列。

可以传递使用 wp_register_script_module 函数注册的脚本模块 ID、相对于 block.json 文件的 JavaScript 模块路径,或两者混合的列表 (了解更多)。

WordPress 脚本和 WordPress 脚本模块目前不兼容。如果前端视图资源依赖于 WordPress 脚本,则应使用 viewScript。如果它们依赖于 WordPress 脚本模块(目前指交互性 API),则应使用 viewScriptModule。脚本模块将逐渐获得更多功能

注意:自 WordPress 6.5.0 版本起可用。

编辑器样式

{ "editorStyle": "file:./index.css" }

区块类型的编辑器样式定义。这些样式仅在编辑器上下文中被加入队列。

可以传递一个通过 wp_register_style 函数注册的样式句柄、一个相对于 block.json 文件的 CSS 文件路径,或者一个包含两者混合的列表 (了解更多)。

注意:从 WordPress 5.9.0 版本开始,支持传递编辑器样式数组。

样式

{ "style": [ "file:./style.css", "example-shared-style" ] }

区块类型的前端和编辑器样式定义。这些样式将在编辑器中以及在前端查看内容时被加入队列。

可以传递一个通过 wp_register_style 函数注册的样式句柄、一个相对于 block.json 文件的 CSS 文件路径,或者一个包含两者混合的列表 (了解更多)。

注意:从 WordPress 5.9.0 版本开始,也支持传递一个样式数组。

视图样式

{ "viewStyle": [ "file:./view.css", "example-view-style" ] }

区块类型的前端样式定义。这些样式仅在网站前端查看内容时才会入队。

可以传递一个通过 wp_register_style 函数注册的样式句柄、一个相对于 block.json 文件的 CSS 文件路径,或者一个包含两者混合的列表 (了解更多)。

仅前端样式对于交互式区块特别有用,用于样式化仅在用户执行某些操作后才可见的部分,并且这些样式在编辑器中永远不需要。你可以从使用 style 属性开始,将所有公共样式放在一个样式表中。只有当你需要编辑器特定样式或前端特定样式时,才扩展到 editorStyleviewStyle,但仍将样式的公共部分保留在主样式表中。

渲染

{ "render": "file:./render.php" }

在服务器端渲染区块类型以在前端显示时使用的 PHP 文件。该文件可以访问以下变量:

通过 render 定义的 render.php 文件的示例实现可能如下所示:

<div <?php echo get_block_wrapper_attributes(); ?>>
    <?php echo esc_html( $attributes['label'] ); ?>
</div>

注意:在服务器上渲染页面 HTML 时,此文件会为区块类型的每个实例加载。在文件中声明函数或类时,必须考虑到这一点。避免错误风险的最简单方法是从另一个文件调用该共享逻辑。

资源文件

WPDefinedPath

WPDefinedPath 类型是字符串的子类型,其值表示相对于 block.json 文件所在位置的 JavaScript、CSS 或 PHP 文件路径。提供的路径必须以 file: 为前缀。此方法基于 npm 处理包的本地路径的方式。

示例:

block.json 中:

{
    "render": "file:./render.php"
}

WPDefinedAsset

它扩展了 WPDefinedPath,用于 JavaScript 和 CSS 文件。文件路径的替代方案可以是脚本句柄、脚本模块 ID 或样式句柄,这些引用的是使用 WordPress 辅助函数已注册的资源。

示例:

block.json 中:

{
    "editorScript": "file:./index.js",
    "script": "file:./script.js",
    "viewScriptModule": [
        "file:./view.js",
        "example-registered-script-module-id"
    ],
    "editorStyle": "file:./index.css",
    "style": [ "file:./style.css", "example-shared-style" ],
    "viewStyle": [ "file:./view.css", "example-view-style" ]
}

在 WordPress 上下文中,当使用 PHP 注册一个区块时,它会自动注册在 block.json 文件中找到的所有脚本、脚本模块和样式,这些资源使用的是文件路径而非资源句柄。

这就是为什么 WPDefinedAsset 类型必须提供一种方式来映射使用 wp_register_scriptwp_register_script_modulewp_register_style 注册脚本、脚本模块和样式所需的参数,然后将这些作为与区块关联的句柄或脚本模块 ID 进行分配。

可以提供一个具有以下结构的对象:

该定义存储在一个单独的 PHP 文件中,该文件以 .asset.php 结尾,并位于 block.json 中列出的 JS/CSS 文件旁边。WordPress 将通过模式匹配自动检测此文件。此选项是首选,因为预计它将成为一个使用 @wordpress/scripts 包自动生成这些资源文件的选项。

示例:

build/
├─ block.json
├─ index.js
└─ index.asset.php

block.json 中:

{ "editorScript": "file:./index.js" }

build/index.asset.php 中:

<?php
return array(
    'dependencies' => array(
        'react',
        'wp-blocks',
        'wp-i18n',
    ),
    'version'      => '3be55b05081a63d8f9d0ecb466c42cfd',
);

前端资源入队

自 WordPress 5.8 版本起,可以指示 WordPress 仅在块类型于前端渲染时,才将其脚本和样式加入队列。这适用于 block.json 文件中的以下资源字段:

国际化

WordPress 字符串发现系统可以自动翻译本文档中标记为可翻译的字段。首先,你需要在提供区块元数据的 block.json 文件中设置 textdomain 属性。

示例:

{
    "title": "My block",
    "description": "My block is fantastic",
    "keywords": [ "fantastic" ],
    "textdomain": "my-plugin"
}

PHP

在 PHP 中,当执行 register_block_type 时,本地化的属性将在 WordPress 后端自动包装在 _x 函数调用中。这些翻译会以内联脚本的形式添加到插件的脚本句柄或 WordPress 核心的 wp-block-library 脚本句柄中。

register_block_type 处理可翻译值的方式大致等同于以下代码片段:

<?php
$metadata = array(
    'title'       => _x( 'My block', 'block title', 'my-plugin' ),
    'description' => _x( 'My block is fantastic!', 'block description', 'my-plugin' ),
    'keywords'    => array( _x( 'fantastic', 'block keyword', 'my-plugin' ) ),
);

其实现遵循现有的 get_plugin_data 函数,该函数解析插件内容以检索插件的元数据,并动态应用翻译。

JavaScript

In JavaScript, you can use registerBlockType method from @wordpress/blocks package and pass the metadata object loaded from block.json as the first param. All localized properties get automatically wrapped in _x (from @wordpress/i18n package) function calls similar to how it works in PHP.

Example:

import { registerBlockType } from '@wordpress/blocks';
import Edit from './edit';
import metadata from './block.json';

registerBlockType( metadata, {
    edit: Edit,
    // ...other client-side settings
} );

Backward compatibility

The existing registration mechanism (both server side and frontend) will continue to work, it will serve as low-level implementation detail for the block.json based registration.

Once all details are ready, Core Blocks will be migrated iteratively and third-party blocks will see warnings appearing in the console to encourage them to refactor the block registration API used.

The following properties are going to be supported for backward compatibility reasons on the client-side only. Some of them might be replaced with alternative APIs in the future:

Example:

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

registerBlockType( 'my-plugin/block-name', {
    edit: function () {
        // Edit definition goes here.
    },
    save: function () {
        // Save definition goes here.
    },
    getEditWrapperProps: function () {
        // Implementation goes here.
    },
} );

In the case of dynamic blocks supported by WordPress, it should still be possible to register the render_callback property using both register_block_type functions on the server.