When you register and store attributes in the WordPress block editor (Gutenberg) you have the option to store them as post meta, instead of the usual block attributes.
Using this method, you could have a setting in your block that can control something post wide, or on the template.
An Important Note About Rendering Post Meta Attributes
You cannot render post meta attributes using a JavaScript save method. A decision was taken by the Gutenberg team to prevent this, because blocks that render post meta fields can easily be broken due to the post meta changing elsewhere on the post.
In this guide we are going to expand on what we have already built in our WordPress Gutenberg plugin guide, and also the Dynamic Block guide.
Prerequisites
- Be familiar with creating plugins for WordPress Gutenberg
- Be familiar dynamic blocks and server side rendering
Registering the Post Meta in PHP
Before we can use a post meta field in JavaScript, we have to make sure that we have registered it in PHP using register_meta
and that the show_in_rest
argument has been set to true.
Following on from the Dynamic Block guide, open up the root PHP file of the plugin (in this case wholesome-plugin.php
) and add the following code to the bottom of that file after all other functions:
function wholesomecode_wholesome_plugin_register_post_meta() {
register_meta(
'post',
'_wholesomecode_wholesome_plugin_block_text',
[
'auth_callback' => '__return_true',
'default' => __( 'Wholesome Plugin – hello from the editor!', 'wholesome-plugin' ),
'show_in_rest' => true,
'single' => true,
'type' => 'string',
]
);
}
add_action( 'init', 'wholesomecode_wholesome_plugin_register_post_meta' );
This code registers a meta field called _wholesomecode_wholesome_plugin_block_text
for the post
post type. It also ensures the REST API can access this meta field with the show_in_rest
value being set to true.
We are also passing the function __return_true
to the auth_callback
argument to ensure we have the permissions to access this parameter. If we wanted better security for this parameter we would alter this to a custom function that checks a certain user role.
Registering the Post Meta Attributes in JavaScript
Again, following on from the previous guide, open up /src/index.js
and replace the attributes
with the following:
attributes: {
blockText: {
meta: '_wholesomecode_wholesome_plugin_block_text',
source: 'meta',
},
},
Instead of stating the type of attribute, and assigning a default value, we instead define the meta key that the data attribute will come from and indicating that the source
of the attribute is meta
.
As indicated in the warning at the top of this guide, you are not able to access post meta field attributes via the JavaScript save
method, so compile the plugin with npm start
and lets see how we can output the meta.
Rendering the Post Meta
Because we have saved our attribute as post meta, we could output this anywhere in WordPress using get_post_meta
(provided we have the $post_id
):
get_post_meta( $post_id, '_wholesomecode_wholesome_plugin_block_text', true );
Continuing the Dynamic Block guide, let’s see how we can access this attribute on the server side in PHP.
The meta is not available via the $attributes
parameter of the render_callback
, as post meta attributes do not pass their value through to this parameter, but we can access the global $post
object to get the post ID.
With this in mind, let’s update our register_block_type
to output the post meta:
register_block_type(
'wholesomecode/wholesome-plugin',
array(
'editor_script' => 'wholesomecode-wholesome-plugin-block-editor',
'editor_style' => 'wholesomecode-wholesome-plugin-block-editor',
'render_callback' => function( $attributes, $content ) {
global $post;
$block_text = get_post_meta( $post->ID, '_wholesomecode_wholesome_plugin_block_text', true );
return "$block_text
";
},
'style' => 'wholesomecode-wholesome-plugin-block',
)
);
Note that we no longer need to register the attributes
here, because we are only accessing the post meta field via the get_post_meta
function.
Using the Block
This isn’t the best use case of this kind of meta, however when we use the block, we can see that because we are storing the attributes as post meta, if we update the attribute in one block, it updates all blocks, as the post meta is stored against the post, not the individual block:
Post Meta Attributes in Action
Extra: Taking it Further
- Have a look at creating nested child blocks with the
InnerBlocks
component - Take using post meta in Gutenberg further by creating Custom Meta Boxes in Gutenberg
- Have a look at using settings to store data in the options table in Gutenberg