As of WordPress 5.8 release, we encourage using block.json
file metadata as the canonical way to register block types. We have been working on Block Metadata specification for a few major WordPress releases, and we reached the point where all planned features are in place.
Example:
notice/block.json
{
"apiVersion": 2,
"name": "my-plugin/notice",
"title": "Notice",
"category": "text",
"parent": [ "core/group" ],
"icon": "star",
"description": "Shows warning, error or success notices…",
"keywords": [ "alert", "message" ],
"textdomain": "my-plugin",
"attributes": {
"message": {
"type": "string",
"source": "html",
"selector": ".message"
}
},
"providesContext": {
"my-plugin/message": "message"
},
"usesContext": [ "groupId" ],
"supports": {
"align": true
},
"styles": [
{ "name": "default", "label": "Default", "isDefault": true },
{ "name": "other", "label": "Other" }
],
"example": {
"attributes": {
"message": "This is a notice!"
}
},
"editorScript": "file:./build/index.js",
"script": "file:./build/script.js",
"editorStyle": "file:./build/index.css",
"style": "file:./build/style.css"
}
The block definition not only allows code sharing between JavaScript, PHP, and other languages when processing block types stored as JSON. More importantly, WordPress Plugins Directory can detect block.json
files and highlight blocks included in plugins. The same file is also used when submitting a block to Block Directory.
TBD - explain why blocks should be registered on the server with block.json
in WordPress
It’s interconnected with https://core.trac.wordpress.org/ticket/50328 (Enqueue script and style assets only for blocks present on the page), Global Styles, Block Directory and Plugins Directory. There is also REST API endpoint for block types - https://developer.wordpress.org/rest-api/reference/block-types/ - that can list only blocks that are registered on the server.
The register_block_type
function that aims to simplify the block type registration on the server, can read now metadata stored in the block.json
file.
The function takes two params relevant in this context ($block_type
accepts more types and variants):
$block_type
(string
) – path to the folder where theblock.json
file is located or full path to the metadata file if named differently.$args
(array
) – an optional array of block type arguments. Default value:[]
. Any arguments may be defined.
It returns the registered block type (WP_Block_Type
) on success or false
on failure.
Example:
notice/notice.php
<?php
register_block_type(
__DIR__,
array(
'render_callback' => 'render_block_core_notice',
)
);
Note: We decided to consolidate the pre-existing functionality available with register_block_type_from_metadata
method into register_block_type
to avoid some confusion that it created. It's still possible to use both functions, but we plan to use only the shorter version in the official documents and tools from now on.
Related Trac ticket: #53233.
If you don’t want to register the block on the server with PHP - not recommended in the context of WordPress – you can use now registerBlockType
method from @wordpress/blocks
package to register a block type using the metadata loaded from block.json
file.
The function takes two params:
$blockNameOrMetadata
(string|Object
) – block type name (supported previously) or the metadata object loaded from theblock.json
file with a bundler (e.g., webpack) or a custom Babel plugin.$settings
(Object
) – client-side block settings.
It returns the registered block type (WPBlock
) on success or undefined
on failure.
Example:
notice/index.js
import { registerBlockType } from '@wordpress/blocks';
import Edit from './edit';
import metadata from './block.json';
registerBlockType( metadata, {
edit: Edit,
// ...other client-side settings
} );
Related PR: WordPress/gutenberg#32030.
WordPress string discovery system can now automatically translate fields marked as translatable in Block Metadata document. First, in the block.json
file that provides block metadata, you need to set the textdomain
property and fields that should be translated.
Example:
fantastic-block/block.json
{
"name": "my-plugin/fantastic-block",
"title": "My block",
"description": "My block is fantastic",
"keywords": [ "fantastic" ],
"textdomain": "fantastic-block"
}
In PHP, localized properties will be automatically wrapped in _x
function calls on the backend of WordPress when executing register_block_type
function. These translations get added as an inline script to the plugin’s script handle or to the wp-block-library
script handle in WordPress core.
The way register_block_type
processes translatable values is roughly equivalent to the following code snippet:
<?php
$metadata = array(
'title' => _x( 'My block', 'block title', 'fantastic-block' ),
'description' => _x( 'My block is fantastic!', 'block description', 'fantastic-block' ),
'keywords' => array( _x( 'fantastic', 'block keyword', 'fantastic-block' ) ),
);
Implementation follows the existing get_plugin_data function which parses the plugin contents to retrieve the plugin’s metadata, and it applies translations dynamically.
Related Trac ticket: #52301.
You can also now use registerBlockType
method from @wordpress/blocks
package to register a block type that uses translatable metadata stored in block.json
file. All localized properties get automatically wrapped in _x
function calls (from @wordpress/i18n
package) similar to how it works in PHP with register_block_type
. The only requirement is to set the textdomain
property in the block.json
file.
Example:
fantastic-block/index.js
import { registerBlockType } from '@wordpress/blocks';
import Edit from './edit';
import metadata from './block.json';
registerBlockType( metadata, {
edit: Edit,
// ...other client-side settings
} );
Related PR: WordPress/gutenberg#30293.
The ongoing effort to improve the internationalization of client-side JavaScript code made necessary by moving to the block-based editor has led to several improvements to the i18n make-pot
command from WP-CLI as of v2.5.0
release. It now also parses the block.json
file as it is defined in the Block Metadata document.
Related PR: wp-cli/i18n-command#210.
There are two new WordPress hooks that can be used when block types get registered with register_block_type
function using the metadata loaded from the block.json
file.
Filters the raw metadata loaded from the block.json
file when registering a block type. It allows applying modifications before the metadata gets processed.
The filter takes one param:
$metadata
(array
) – metadata loaded fromblock.json
for registering a block type.
Example:
<?php
$filter_metadata_registration = function( $metadata ) {
$metadata['apiVersion'] = 1;
return $metadata;
};
add_filter( 'block_type_metadata', $filter_metadata_registration, 10, 2 );
register_block_type_from_metadata( __DIR__ );
Filters the settings determined from the processed block type metadata. It makes it possible to apply custom modifications using the block metadata that isn't handled by default.
The filter takes two params:
$settings
(array
) – Array of determined settings for registering a block type.$metadata
(array
) – Metadata loaded from theblock.json
file.
Example:
$filter_metadata_registration = function( $settings, $metadata ) {
$settings['api_version'] = $metadata['apiVersion'] + 1;
return $settings;
};
add_filter( 'block_type_metadata_settings', $filter_metadata_registration, 10, 2 );
register_block_type_from_metadata( __DIR__ );