Custom fields provide a way to assign extra information to website content. These bits of information are usually known as metadata.
Metadata is information about information. In the case of WordPress, it’s information associated with posts, users, comments and terms.
Given the many-to-one relationship of metadata in WordPress, your options are fairly limitless. You can have as many meta options as you wish, and you can store just about anything in there.
Here are some examples of metadata you can attach to a post using custom fields:
- The geographic coordinates of a place or real estate
- The date of an event
- The ISBN or author of a book
- The mood of the day of the author of the post
And there are plenty more.
Out of the box, WordPress does not provide an easy way to add and manage custom fields. In the Classic Editor, custom fields are displayed in a box placed at the bottom of the page, below the post editor.
In Gutenberg, custom fields are disabled by default, but you can display them by selecting the corresponding item in post settings.
Unfortunately, there is no way to display metadata on the frontend without using a plugin or getting your hands dirty with code.
If you’re a user, you’ll find several excellent plugins doing the job for you out there. But if you’re a developer and want to get more out of WordPress custom fields, integrate them seamlessly into the block editor, and display them on the frontend of your WordPress website using a custom Gutenberg block, then you’re in the right place.
So, if you’re wondering what is the best way to use WordPress custom fields both in Gutenberg and the Classic Editor for WordPress developers, the quick answer is “creating a plugin that works for both the Classic Editor and Gutenberg”.
But don’t worry too much. If creating a plugin to manage custom fields in both editors could be a little tricky, we’ll try to make the process as straightforward as possible. Once you understand the concepts we’ll discuss in this article, you’ll gain the skills needed to manage custom meta fields in Gutenberg and build all kinds of websites.
Note: Before doing anything, make sure you have an up-to-date version of Node.js on your computer
That having been said, here is our rundown:
Create a Block Plugin With the Official create-block Tool
The first step is to create a new plugin with all the files and dependencies needed to register a new block type. The block plugin will allow you to easily build a custom block type for managing and displaying custom metadata.
To create a new block type, we’ll use the official create-block tool. For a detailed overview of how to use the create-block tool, check out our previous article about Gutenberg block development.
Open your command line tool, navigate to the plugins directory of your WordPress development website and run the following command:
npx @wordpress/create-block
When prompted, add the following details:
- The template variant to use for this block: dynamic
- The block slug used for identification (also the output folder name): metadata-block
- The internal namespace for the block name (something unique for your products): meta-fields
- The display title for your block: Meta Fields
- The short description for your block (optional): Block description
- The dashicon to make it easier to identify your block (optional): book
- The category name to help users browse and discover your block: widgets
- Do you want to customize the WordPress plugin? Yes/No
Let’s take a moment to review those details and try to understand where they are used.
- The block slug used for identification defines the plugin’s folder name and textdomain
- The internal namespace for the block name defines the block internal namespace and function prefix used throughout the plugin’s code.
- The display title for your block defines the plugin name and the block name used in the editor interface.
The setup may take a couple of minutes. When the process is completed, you’ll get a list of the available commands.
Before moving on to the next section, in your command line tool, navigate to your plugin’s folder and run the following commands:
cd metadata-block
npm start
You are ready to build your code. The next step is to edit the main PHP file of the plugin to build a meta box for the Classic Editor.
So, before moving on to the next section, install and activate the Classic Editor plugin.
Then, open the Plugins screen and activate the new Meta Fields plugin.
Add a Meta Box to the Classic Editor
In the context of the Classic Editor, a meta box is a container holding form elements to type in specific bits of information, such as the post author, tags, categories, etc.
In addition to the built-in meta boxes, plugin developers can add any number of custom meta boxes to include HTML form elements (or any HTML content) where plugin users can enter plugin-specific data.
The WordPress API provides useful functions to easily register custom meta boxes to include all the HTML elements your plugin needs to work.
To get started, append the following code to the PHP file of the plugin you’ve just created:
// register meta box
function meta_fields_add_meta_box(){
add_meta_box(
'meta_fields_meta_box',
__( 'Book details' ),
'meta_fields_build_meta_box_callback',
'post',
'side',
'default'
);
}
// build meta box
function meta_fields_build_meta_box_callback( $post ){
wp_nonce_field( 'meta_fields_save_meta_box_data', 'meta_fields_meta_box_nonce' );
$title = get_post_meta( $post->ID, '_meta_fields_book_title', true );
$author = get_post_meta( $post->ID, '_meta_fields_book_author', true );
?>
<div class="inside">
<p><strong>Title</strong></p>
<p><input type="text" id="meta_fields_book_title" name="meta_fields_book_title" value="<?php echo esc_attr( $title ); ?>" /></p>
<p><strong>Author</strong></p>
<p><input type="text" id="meta_fields_book_author" name="meta_fields_book_author" value="<?php echo esc_attr( $author ); ?>" /></p>
</div>
<?php
}
add_action( 'add_meta_boxes', 'meta_fields_add_meta_box' );
The add_meta_box
function registers a new meta box, while the callback function builds the HTML to be injected into the meta box. We won’t dive deeper into this topic because it’s beyond the scope of our article, but you’ll find all the details you need here, here and here.
The next step is to create a function that saves the data entered by the post author anytime the save_post
hook is triggered (see Developer Resources):
// save metadata
function meta_fields_save_meta_box_data( $post_id ) {
if ( ! isset( $_POST['meta_fields_meta_box_nonce'] ) )
return;
if ( ! wp_verify_nonce( $_POST['meta_fields_meta_box_nonce'], 'meta_fields_save_meta_box_data' ) )
return;
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return;
if ( ! current_user_can( 'edit_post', $post_id ) )
return;
if ( ! isset( $_POST['meta_fields_book_title'] ) )
return;
if ( ! isset( $_POST['meta_fields_book_author'] ) )
return;
$title = sanitize_text_field( $_POST['meta_fields_book_title'] );
$author = sanitize_text_field( $_POST['meta_fields_book_author'] );
update_post_meta( $post_id, '_meta_fields_book_title', $title );
update_post_meta( $post_id, '_meta_fields_book_author', $author );
}
add_action( 'save_post', 'meta_fields_save_meta_box_data' );
Again, check out the online documentation for details. Here we’ll just point out the underscore character (_
) preceding the meta key. This tells WordPress to hide the keys of these custom fields from the list of custom fields available by default and makes your custom fields visible only in your custom meta box.
The image below shows what the custom meta box looks like in the Classic Editor:
Now, if you disable the Classic Editor plugin and check what happens in the block editor, you’ll see that the meta box still appears and works, but not exactly in the way you might expect.
Our goal is to create a system for managing metadata attached to blog posts or custom post types that integrates seamlessly within the block editor. For this reason, the code shown so far will only be needed to ensure backward compatibility with the Classic Editor.
So, before moving on, we’ll tell WordPress to remove the custom meta box from the block editor by adding the __back_compat_meta_box
flag to the add_meta_box
function (see also Meta Box Compatibility Flags and Backward Compatibility).
Let’s get back to the callback function that registers the meta box and change it as follows:
// register meta box
function meta_fields_add_meta_box(){
add_meta_box(
'meta_fields_meta_box',
__( 'Book details' ),
'meta_fields_build_meta_box_callback',
'post',
'side',
'default',
// hide the meta box in Gutenberg
array('__back_compat_meta_box' => true)
);
}
Save the plugin file and go back to your WordPress admin. Now, you shouldn’t see the custom meta box in the block editor anymore. If you reactivate the Classic Editor instead, your custom meta box will show up again.
Add Custom Meta Fields to the Gutenberg Block Editor (Three Options)
In our previous articles about Gutenberg block development, we provided detailed overviews of the editor, its parts, and how to develop static blocks and dynamic blocks.
As we mentioned, in this article we’ll take it a step further and discuss how to add custom meta fields to blog posts.
There are several ways to store and use post metadata in Gutenberg. Here we’ll cover the following:
Create a Custom Block To Store and Display Custom Meta Fields
In this section, we’ll show you how to create and manage custom meta fields from within a dynamic block. According to the Block Editor Handbook, a post meta field “is a WordPress object used to store extra data about a post” and we need to first register a new meta field before we can use it.
Register Custom Meta Fields
Before registering a custom meta field, you need to make sure that the post type that will use it supports custom fields. In addition, when you register a custom meta field, you should set the show_in_rest
parameter to true
.
Now, back to the plugin file. Add the following code:
/**
* Register the custom meta fields
*/
function meta_fields_register_meta() {
$metafields = [ '_meta_fields_book_title', '_meta_fields_book_author' ];
foreach( $metafields as $metafield ){
// Pass an empty string to register the meta key across all existing post types.
register_post_meta( '', $metafield, array(
'show_in_rest' => true,
'type' => 'string',
'single' => true,
'sanitize_callback' => 'sanitize_text_field',
'auth_callback' => function() {
return current_user_can( 'edit_posts' );
}
));
}
}
add_action( 'init', 'meta_fields_register_meta' );
register_post_meta
registers a meta key for the specified post types. In the code above, we have registered two custom meta fields for all post types registered on your website that support custom fields. For more information, see the function reference.
Once done, open the src/index.js file of your block plugin.
Register the Block Type on the Client
Now navigate to the wp-content/plugins/metadata-block/src folder and open the index.js file:
import { registerBlockType } from '@wordpress/blocks';
import './style.scss';
import Edit from './edit';
import metadata from './block.json';
registerBlockType( metadata.name, {
edit: Edit,
} );
With static blocks we would also have seen a save
function. In this case, the save
function is missing because we installed a dynamic block. The content shown on the frontend will be generated dynamically via PHP.
Build the Block Type
Navigate to the wp-content/plugins/metadata-block/src folder and open the edit.js file. You should see the following code (comments removed):
import { __ } from '@wordpress/i18n';
import { useBlockProps } from '@wordpress/block-editor';
import './editor.scss';
export default function Edit() {
return (
<p { ...useBlockProps() }>
{ __( 'Meta Fields – hello from the editor!', 'metadata-block' ) }
</p>
);
}
Here you’ll add the code to generate the block to be rendered in the editor.
The first step is to import the components and functions needed to build the block. Here is the complete list of dependencies:
import { __ } from '@wordpress/i18n';
import { useBlockProps, InspectorControls, RichText } from '@wordpress/block-editor';
import { useSelect } from '@wordpress/data';
import { useEntityProp } from '@wordpress/core-data';
import { TextControl, PanelBody, PanelRow } from '@wordpress/components';
import './editor.scss';
If you’ve read our previous articles, you should be familiar with many of these import
declarations. Here we’ll point out just a couple of them:
import { useSelect } from '@wordpress/data';
import { useEntityProp } from '@wordpress/core-data';
Once you’ve imported these dependencies, here is how you’ll useSelect
and useEntityProp
in the Edit()
function:
const postType = useSelect(
( select ) => select( 'core/editor' ).getCurrentPostType(),
[]
);
const [ meta, setMeta ] = useEntityProp( 'postType', postType, 'meta' );
useSelect
is a custom hook for retrieving props from registered selectors. We will use it to retrieve the current post type (see also @wordpress/data reference and Introducing useDispatch and useSelect)useEntityProp
is a custom hook that allows blocks to retrieve and change post meta fields. It’s defined as a “hook that returns the value and a setter for the specified property of the nearest provided entity of the specified type”. It returns “an array where the first item is the property value, the second is the setter and the third is the full value object from REST API containing more information likeraw
,rendered
andprotected
props”. (See also General Block Editor API Updates.)
This code provides the current postType
, an object of meta fields (meta
), and a setter function to update them (setMeta
).
Now replace the current code for the Edit()
function with the following:
export default function Edit() {
const blockProps = useBlockProps();
const postType = useSelect(
( select ) => select( 'core/editor' ).getCurrentPostType(),
[]
);
const [ meta, setMeta ] = useEntityProp( 'postType', postType, 'meta' );
const bookTitle = meta[ '_meta_fields_book_title' ];
const bookAuthor = meta[ '_meta_fields_book_author' ];
const updateBookTitleMetaValue = ( newValue ) => {
setMeta( { ...meta, _meta_fields_book_title: newValue } );
};
const updateBookAuthorMetaValue = ( newValue ) => {
setMeta( { ...meta, _meta_fields_book_author: newValue } );
};
return ( ... );
}
Again:
- We used
useSelect
to get the current post type. useEntityProp
returns an array of meta fields and a setter function to set new meta values.updateBookTitleMetaValue
andupdateBookAuthorMetaValue
are two event handlers to save meta field values.
The next step is to build the JSX (JavaScript XML) code returned by the Edit()
function:
export default function Edit() {
...
return (
<>
<InspectorControls>
<PanelBody
title={ __( 'Book Details' )}
initialOpen={true}
>
<PanelRow>
<fieldset>
<TextControl
label={__( 'Book title' )}
value={ bookTitle }
onChange={ updateBookTitleMetaValue }
/>
</fieldset>
</PanelRow>
<PanelRow>
<fieldset>
<TextControl
label={ __( 'Book author' ) }
value={ bookAuthor }
onChange={ updateBookAuthorMetaValue }
/>
</fieldset>
</PanelRow>
</PanelBody>
</InspectorControls>
<div { ...blockProps }>
<RichText
tagName="h3"
onChange={ updateBookTitleMetaValue }
allowedFormats={ [ 'core/bold', 'core/italic' ] }
value={ bookTitle }
placeholder={ __( 'Write your text...' ) }
/>
<TextControl
label="Book Author"
value={ bookAuthor }
onChange={ updateBookAuthorMetaValue }
/>
</div>
</>
);
}
The RichText
component provides a contenteditable input, while TextControl
provides simple text fields.
We also created a sidebar panel containing two input fields to use instead of the two form controls included in the block.
Save the file and go back to the editor. Add the Meta Fields block from the block inserter and fill in the book title and author.
You will notice that whenever you change the value of the field in the block, the value in the corresponding text field in the sidebar will also change.
Next, we have to create the PHP code that generates the HTML to be rendered on the frontend.
Display the Block on the Frontend
Open the main PHP file again in your code editor and rewrite the callback function that generates the output of the block as follows:
function meta_fields_metadata_block_block_init() {
register_block_type(
__DIR__ . '/build',
array(
'render_callback' => 'meta_fields_metadata_block_render_callback',
)
);
}
add_action( 'init', 'meta_fields_metadata_block_block_init' );
function meta_fields_metadata_block_render_callback( $attributes, $content, $block ) {
$book_title = get_post_meta( get_the_ID(), '_meta_fields_book_title', true );
$book_author = get_post_meta( get_the_ID(), '_meta_fields_book_author', true );
$output = "";
if( ! empty( $book_title ) ){
$output .= '<h3>' . esc_html( $book_title ) . '</h3>';
}
if( ! empty( $book_author ) ){
$output .= '<p>' . __( 'Book author: ' ) . esc_html( $book_author ) . '</p>';
}
if( strlen( $output ) > 0 ){
return '<div ' . get_block_wrapper_attributes() . '>' . $output . '</div>';
} else {
return '<div ' . get_block_wrapper_attributes() . '>' . '<strong>' . __( 'Sorry. No fields available here!' ) . '</strong>' . '</div>';
}
}
This code is quite self-explanatory. First, we use get_post_meta
to retrieve the values of the custom meta fields. Then we use those values to build the block content. Finally, the callback function returns the HTML of the block.
The block is ready to be used. We intentionally kept the code in this example as simple as possible but using Gutenberg’s native components you can build more advanced blocks and get the most from WordPress custom meta fields.
In our example, we used h3
and p
elements to build the block for the frontend.
But you can display the data in many ways. The following image shows a simple unordered list of meta fields.
You’ll find the complete code of this example in this public gist.
Adding a Custom Meta Box to the Document Sidebar
The second option is to attach custom meta fields to posts using a plugin that generates a settings panel in the Document Sidebar.
The process is pretty similar to the previous example, except that in this case, we won’t need a block to manage metadata. We will create a component to generate a panel including a set of controls in the Document sidebar following these steps:
- Create a new block plugin with create-block
- Register a custom meta box for the Classic Editor
- Register the custom meta fields in the main plugin file via the register_post_meta() function
- Register a plugin in the index.js file
- Build the component using built-in Gutenberg components
Create a New Block Plugin With the create-block Tool
To create a new block plugin, follow the steps in the previous section. You can create a new plugin or edit the scripts we built in the previous example.
Register a Custom Meta Box for the Classic Editor
Next, you need to register a custom meta box to ensure backward compatibility for WordPress websites still using the Classic Editor. The process is the same as described in the previous section.
Register the Custom Meta Fields in the Main Plugin File
The next step is to register the custom meta fields in the main plugin file via the register_post_meta()
function. Again, you can follow the previous example.
Register a Plugin in the index.js File
Once you’ve completed the previous steps, it is time to register a plugin in the index.js file to render a custom component.
Before registering the plugin, create a components folder inside the plugin’s src folder. Inside the components folder, create a new MetaBox.js file. You can choose whatever name you think is good for your component. Just make sure to follow the best practice for naming in React.
Before moving on, install the @wordpress/plugins
module from your command line tool.
Stop the process (mac), install the module and start the process again:
^C
npm install @wordpress/plugins --save
npm start
Once done, open the index.js file of your plugin and add the following code.
/**
* Registers a plugin for adding items to the Gutenberg Toolbar
*
* @see https://developer.wordpress.org/block-editor/reference-guides/slotfills/plugin-sidebar/
*/
import { registerPlugin } from '@wordpress/plugins';
import MetaBox from './components/MetaBox';
This code is fairly self-explanatory. However, we want to take a moment to dwell on the two import
statements for those readers who do not have advanced React skills.
With the first import
statement, we enclosed the name of the function in curly brackets. With the second import
statement, the name of the component is not enclosed in curly brackets.
Next, register your plugin:
registerPlugin( 'metadata-plugin', {
render: MetaBox
} );
registerPlugin
simply registers a plugin. The function accepts two parameters:
- A unique string that identifies the plugin
- An object of plugin settings. Note that the
render
property must be specified and must be a valid function.
Build the Component Using Built-in Gutenberg Components
It’s time to build our React component. Open the MetaBox.js file (or whatever you called it) and add the following import statements:
import { __ } from '@wordpress/i18n';
import { compose } from '@wordpress/compose';
import { withSelect, withDispatch } from '@wordpress/data';
import { PluginDocumentSettingPanel } from '@wordpress/edit-post';
import { PanelRow, TextControl, DateTimePicker } from '@wordpress/components';
- The
compose
function performs function composition, meaning that the result of a function is passed on to another function.Before you can usecompose
, you may need to install the corresponding module:npm install @wordpress/compose --save
We’ll see the
compose
function in action in a moment. withSelect
andwithDispatch
are two higher order components that allow you to fetch or dispatch data from or to a WordPress store.withSelect
is used to inject state-derived props using registered selectors,withDispatch
is used to dispatch props using registered action creators.PluginDocumentSettingPanel
renders items in the Document Sidebar (see the source code on Github).
Next, you’ll create the component to display the meta box panel in the Document sidebar. In your MetaBox.js file, add the following code:
const MetaBox = ( { postType, metaFields, setMetaFields } ) => {
if ( 'post' !== postType ) return null;
return(
<PluginDocumentSettingPanel
title={ __( 'Book details' ) }
icon="book"
initialOpen={ false }
>
<PanelRow>
<TextControl
value={ metaFields._meta_fields_book_title }
label={ __( "Title" ) }
onChange={ (value) => setMetaFields( { _meta_fields_book_title: value } ) }
/>
</PanelRow>
<PanelRow>
<TextControl
value={ metaFields._meta_fields_book_author }
label={ __( "Author" ) }
onChange={ (value) => setMetaFields( { _meta_fields_book_author: value } ) }
/>
</PanelRow>
<PanelRow>
<TextControl
value={ metaFields._meta_fields_book_publisher }
label={ __( "Publisher" ) }
onChange={ (value) => setMetaFields( { _meta_fields_book_publisher: value } ) }
/>
</PanelRow>
<PanelRow>
<DateTimePicker
currentDate={ metaFields._meta_fields_book_date }
onChange={ ( newDate ) => setMetaFields( { _meta_fields_book_date: newDate } ) }
__nextRemoveHelpButton
__nextRemoveResetButton
/>
</PanelRow>
</PluginDocumentSettingPanel>
);
}
const applyWithSelect = withSelect( ( select ) => {
return {
metaFields: select( 'core/editor' ).getEditedPostAttribute( 'meta' ),
postType: select( 'core/editor' ).getCurrentPostType()
};
} );
const applyWithDispatch = withDispatch( ( dispatch ) => {
return {
setMetaFields ( newValue ) {
dispatch('core/editor').editPost( { meta: newValue } )
}
}
} );
export default compose([
applyWithSelect,
applyWithDispatch
])(MetaBox);
Let’s break down this code.
- The
PluginDocumentSettingPanel
element renders a new panel in the Document sidebar. We set the title (“Book details”) and icon, and setinitialOpen
tofalse
, which means that initially the panel is closed. - Within the
PluginDocumentSettingPanel
we have three text fields and aDateTimePicker
element that allows the user to set the publication date. withSelect
provides access to theselect
function that we are using to retrievemetaFields
andpostType
.withDispatch
provides access to thedispatch
function, which allows to update the metadata values.- Finally, the
compose
function allows us to compose our component withwithSelect
andwithDispatch
higher-order components. This gives the component access to themetaFields
andpostType
properties and thesetMetaFields
function.
Save your MetaBox.js file and create a new post in your WordPress development website and take a look at the Document Sidebar. You should see the new Book details panel.
Now run your tests. Set the values of your custom meta fields and save the post. Then reload the page and check if the values you entered are in place.
Add the block we have built in the previous section and check if everything is working properly.
Adding a Custom Sidebar To Manage Post Meta Data
If you have a large number of custom meta fields to add to your posts or custom post types, you could also create a Custom Settings Sidebar specifically for your plugin.
The process is very similar to the previous example, so if you’ve understood the steps discussed in the previous section, you won’t have any difficulty with building a Custom Sidebar for Gutenberg.
Again:
- Create a new block plugin with create-block
- Register a custom meta box for the Classic Editor
- Register the custom meta fields in the main plugin file via the register_post_meta() function
- Register a plugin in the index.js file
- Build the component using built-in Gutenberg components
Create a New Block Plugin With the create-block Tool
Again, to create a new block plugin, follow the steps discussed above. You can create a new plugin or edit the scripts built in the previous examples.
Register a Custom Meta Box for the Classic Editor
Now register a custom meta box to ensure backward compatibility for WordPress websites still using the Classic Editor. The process is the same as described in the previous section.
Register the Custom Meta Fields in the Main Plugin File
Register the custom meta fields in the main plugin file via the register_post_meta()
function.
Register a Plugin in the index.js File
Now create an empty CustomSidebar.js file in your components folder.
Once done, change your index.js file as follows:
/**
* Registers a plugin for adding items to the Gutenberg Toolbar
*
* @see https://developer.wordpress.org/block-editor/reference-guides/slotfills/plugin-sidebar/
*/
import { registerPlugin } from '@wordpress/plugins';
import CustomSidebar from './components/CustomSidebar';
// import MetaBox from './components/MetaBox';
registerPlugin( 'metadata-block', {
render: CustomSidebar
} );
With the code above we first import the CustomSidebar
component, then we tell the registerPlugin
function to render the new component.
Build the Component Using Built-in Gutenberg Components
Next, open the CustomSidebar.js file and add the following dependencies:
import { __ } from '@wordpress/i18n';
import { compose } from '@wordpress/compose';
import { withSelect, withDispatch } from '@wordpress/data';
import { PluginSidebar, PluginSidebarMoreMenuItem } from '@wordpress/edit-post';
import { PanelBody, PanelRow, TextControl, DateTimePicker } from '@wordpress/components';
You should notice that we are importing two new components:
PluginSidebar
adds an icon into the Gutenberg Toolbar that, when clicked, displays a sidebar including the content wrapped in the<PluginSidebar />
element (The component is also documented on GitHub).PluginSidebarMoreMenuItem
renders a menu item under Plugins in More Menu dropdown and can be used to activate the correspondingPluginSidebar
component (see also on GitHub).
Now you can build your custom component:
const CustomSidebar = ( { postType, metaFields, setMetaFields } ) => {
if ( 'post' !== postType ) return null;
return (
<>
<PluginSidebarMoreMenuItem
target="metadata-sidebar"
icon="book"
>
Metadata Sidebar
</PluginSidebarMoreMenuItem>
<PluginSidebar
name="metadata-sidebar"
icon="book"
title="My Sidebar"
>
<PanelBody title="Book details" initialOpen={ true }>
<PanelRow>
<TextControl
value={ metaFields._meta_fields_book_title }
label={ __( "Title" ) }
onChange={ (value) => setMetaFields( { _meta_fields_book_title: value } ) }
/>
</PanelRow>
<PanelRow>
<TextControl
value={ metaFields._meta_fields_book_author }
label={ __("Author", "textdomain") }
onChange={ (value) => setMetaFields( { _meta_fields_book_author: value } ) }
/>
</PanelRow>
<PanelRow>
<TextControl
value={ metaFields._meta_fields_book_publisher }
label={ __("Publisher", "textdomain") }
onChange={ (value) => setMetaFields( { _meta_fields_book_publisher: value } ) }
/>
</PanelRow>
<PanelRow>
<DateTimePicker
currentDate={ metaFields._meta_fields_book_date }
onChange={ ( newDate ) => setMetaFields( { _meta_fields_book_date: newDate } ) }
__nextRemoveHelpButton
__nextRemoveResetButton
/>
</PanelRow>
</PanelBody>
</PluginSidebar>
</>
)
}
The final step is the component composition with withSelect
and withDispatch
higher-order components:
const applyWithSelect = withSelect( ( select ) => {
return {
metaFields: select( 'core/editor' ).getEditedPostAttribute( 'meta' ),
postType: select( 'core/editor' ).getCurrentPostType()
};
} );
const applyWithDispatch = withDispatch( ( dispatch ) => {
return {
setMetaFields ( newValue ) {
dispatch('core/editor').editPost( { meta: newValue } )
}
}
} );
export default compose([
applyWithSelect,
applyWithDispatch
])(CustomSidebar);
Save your changes, then check the editor interface. If you open the Options dropdown, you’ll see a new Metadata Sidebar item under the Plugins section. Clicking on the new item will activate your brand-new custom sidebar.
The same happens when you click on the book icon in the upper right corner.
Now go back to your development website, and create a new blog post. Fill in your meta fields, then add the block to the editor’s canvas. It should include the same meta values you entered in your custom sidebar.
Save the post and preview the page on the frontend. You should see your card including the book title, author, publisher, and publication date.
You’ll find the full code of this article in this public gist.
Further Readings
In this article, we covered multiple topics, from selectors to higher-order components and much more. We’ve linked the top resources we used for reference throughout the article as well.
But if you wish to dive deeper into those topics, you may also want to check the following additional resources:
Gutenberg Documentation and Official WordPress Resources
- Plugin Handbook / Custom Meta Boxes
- Plugin Handbook / Managing Post Metadata
- How-to Guides / Meta Boxes
- How-to Guides / Plugin Sidebar
- Block Editor Handbook / PluginSidebar
- Package Reference / @wordpress/compose
- Packages / data / Comparison with Redux
- Packages / data / withDispatch
- Packages / data / dispatch
- Packages / data / withSelect
- Packages / data / select
More Official Resources
- Higher-Order Components in React
- Action creators in Redux
- Deriving Data with Selectors in Redux
Additional Resources From the Community
- Fantastic hooks and where to use them (by Darren Ethier)
- WordPress Data Series Overview and Introduction (by Darren Ethier)
- Airbnb React/JSX Style Guide
- React Higher-Order Components (HOCs) (by Robin Wieruch)
- Function composition in JavaScript
- Requesting data in Gutenberg with getEntityRecords (by Ryan Welcher)
Useful Readings From the Kinsta Website
- What Is React.js? A Look at the Popular JavaScript Library
- React Best Practices to up Your Game
- React UI Components Libraries
- How To Create an Effective WordPress Workflow for Developers
- WordPress Developer Salary: The Average, Plus How to Increase Yours
- What Is JavaScript? A Look at the Web’s Most Popular Scripting Language
- A Definitive Guide to Handling Errors in JavaScript
- The 40 Best JavaScript Libraries and Frameworks for 2023
Summary
In this third article in our series on Gutenberg block development, we covered new advanced topics that should make the picture outlined in previous articles on static and dynamic block development more complete.
You should now be able to take advantage of the potential of custom fields in Gutenberg and create more advanced and functional WordPress websites.
But there’s more. With the skills you’ve gained from our articles on block development, you should also have a good idea of how to develop React components outside of WordPress. After all, Gutenberg is a React-based SPA.
And now it’s down to you! Have you already created Gutenberg blocks that use custom meta fields? Share your creations with us in the comments below.
Leave a Reply