Custom WordPress and WooCommerce Development

Add a meta field to the Block Editor sidebar

Here’s what we’re making

A screenshot of the WordPress post editor. In the right sidebar there's a red square highlighting an area titled "Your Meta Field" and directly beneath it there's a text input with the value "It's pizza friday yay"



This post assumes that you have some basics about getting set up in a block-building environment. So we are going to use following to scaffold an example plugin with block scripts all ready to start:

npx @wordpress/create-block example-post-metaCode language: CSS (css)

After that’s installed you will want to start watching the files by navigating to that new folder and starting the WordPress build scripts.

cd example-post-meta
npm run start

This post is going to focus on adding a meta field to the side bar and less on creating a block to display that.

In the main plugin file example-post-meta.php we need to register our meta key so that the block editor can access it via the REST API


/**
 * Registers the meta key for REST API usage in the Block Editor.
 *
 * @see https://developer.wordpress.org/reference/functions/register_meta/
 */
function example_post_meta_register_meta() {

	register_meta ('post', 'your_meta_key', 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', 'example_post_meta_register_meta' );
Code language: PHP (php)

Next we will create a new file called src/sidebar.js

This is the file where the magic happens.

/**
 * External Dependencies
 */
import { TextControl } from '@wordpress/components';
import { useSelect } from '@wordpress/data';
import { useEntityProp } from '@wordpress/core-data';
import { PluginDocumentSettingPanel } from '@wordpress/edit-post';
import { registerPlugin } from '@wordpress/plugins';
import { __ } from "@wordpress/i18n";

const ExampleMetaPanel = (props) => {

    const { getCurrentPostType } = useSelect('core/editor');

    const postType = getCurrentPostType();

    // If no post type is selected (for example, if in Site Editor), return null.
    if ( ! postType ) {
        return null;
    }

    const [meta, setMeta] = useEntityProp('postType', postType, 'meta');
    const metaValue = meta?.your_meta_key || '';

    const updateYourMeta = (newValue) => {
        setMeta({ ...meta, your_meta_key: newValue });
    };
    
    return (
        <PluginDocumentSettingPanel
            name="example-post-meta-panel"
            title={__("Your Meta Field", "example-post-meta")}
            className="example-post-meta-panel"
        >
            <TextControl
                value={metaValue}
                onChange={updateYourMeta}
            />
        </PluginDocumentSettingPanel>
    );
}

registerPlugin( 'example-post-meta', {
	render: ExampleMetaPanel,
	icon: 'edit',
} );

Code language: JavaScript (javascript)



It’s pretty standard for a react functional component. It imports the dependencies it is going to need and returns some components. But let’s take a closer look at this part in particular:

    const { getCurrentPostType } = useSelect('core/editor');

    const postType = getCurrentPostType();

    // If no post type is selected (for example, if in Site Editor), return null.
    if ( ! postType ) {
        return null;
    }

    const [meta, setMeta] = useEntityProp('postType', postType, 'meta');
    const metaValue = meta?.your_meta_key || '';

    const updateYourMeta = (newValue) => {
        setMeta({ ...meta, your_meta_key: newValue });
    };Code language: JavaScript (javascript)

Here, we utilize the useSelect hook to retrieve the current post type from the editor. If we don’t have a post type, we might be on the Site Editor or some other type of custom content and we won’t be able to get classic post meta anyway so we quit early.

Then we use useEntityProp, to fetch and manage the meta data associated with the current post type. Unfortunately, this one seems (at the time of writing) entirely undocumented. But this custom React hook appears to allow us to access the current post’s properties…. including it’s meta.

We grab our specific property out of the post meta, if it exists. And finally, we write a little helper updateYourMeta to update our specific meta key whenever the user interacts with the interface.

You might have noticed nothing has happened yet in the editor. The last piece is to tell the index.js to include your new sidebar.js when it compiles. To do this you need to open up src/index.js and right after the last of the internal dependencies, add the line

import './sidebar';Code language: JavaScript (javascript)

The next time you load the post editor you should now see a section in the sidebar with a text input.


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *