Here’s what we’re making
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-meta
Code 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.
Leave a Reply