Starting in WordPress 5.8 release, we encourage using the block.json
metadata file as the canonical way to register block types. The Block Metadata specification has been implemented and iterated over the last few major WordPress releases, and we have reached the point where all planned features are in place.
Example File
Here is an example block.json
file that would define the metadata for a plugin create a notice block.
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"
}
Benefits using the metadata file
The block definition allows code sharing between JavaScript, PHP, and other languages when processing block types stored as JSON, and registering blocks with the block.json
metadata file provides multiple benefits on top of it.
From a performance perspective, when themes support lazy loading assets, blocks registered with block.json
will have their asset enqueuing optimized out of the box. The frontend CSS and JavaScript assets listed in the style
or script
properties will only be enqueued when the block is present on the page, resulting in reduced page sizes.
Furthermore, because the Block Type REST API Endpoint can only list blocks registered on the server, registering blocks server-side is recommended; using the block.json
file simplifies this registration.
Last, but not least, the WordPress Plugins Directory can detect block.json
files, highlight blocks included in plugins, and extract their metadata. If you wish to submit your block(s) to the Block Directory, all blocks contained in your plugin must have a block.json
file for the Block Directory to recognize them.
Block registration
PHP
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 the block.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.
JavaScript
If you don’t want to register the block on the server with PHP – not recommended in the context of WordPress for the reasons above – 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 the block.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.
Internationalization support in block.json
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"
}
PHP
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.
JavaScript
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.
Extracting translations
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.
New filters
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 from block.json
for registering a block type.
Example:
<?php
function filter_metadata_registration( $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 the block.json
file.
Example:
function filter_metadata_registration( $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__ );
Props to @priethor and @audrasjb for help with compiling this dev note.
#5-8, #dev-notes, #gutenberg
Thank you @mamaduka for handling this release and for the excellent release notes and “What’s New” post.