How to do this in the “new” way?
From this:
To this:
Creating a custom field using a custom meta box is simple and very straightforward.
Basically we create a meta box using meta box API and add it in post meta data using save_post
hook.
Here’s the basic code:
// Add field: add_action( 'add_meta_boxes', function() { add_meta_box( 'my_meta_box', 'My Meta Box', function( $post ) { wp_nonce_field( __FILE__, '_my_data_nonce' ); ?> <p><input type="text" class="large-text" name="my_data" value="<?php echo esc_attr( get_post_meta( $post->ID, '_my_data', true ) ); ?>"></p> <?php }, 'post', 'side' ); } ); // Save field. add_action( 'save_post', function( $post_id ) { if ( isset( $_POST['my_data'], $_POST['_my_data_nonce'] ) && wp_verify_nonce( $_POST['_my_data_nonce'], __FILE__ ) ) { update_post_meta( $post_id, '_my_data', sanitize_text_field( $_POST['my_data'] ) ); } } );
But how to do this in the new way?
Note: the “old” way still works, but we need to learn to do this in “new” way to get all the latest and greatest features in WordPress.
#1 Register Field in Rest Endpoint
Gutenberg/block editor is using javascript and REST API, so to make this custom field editable via block editor, we need to register this field and make it available in WordPress REST API:
register_post_meta( 'post', '_my_data', [ 'show_in_rest' => true, 'single' => true, 'type' => 'string', 'auth_callback' => function() { return current_user_can( 'edit_posts' ); } ] );
You can read more about it here: https://developer.wordpress.org/reference/functions/register_post_meta/
#2 Create Field Using JS
So, we need to create a js script, and create/register editor plugin, and create a “meta box” using “PluginDocumentSettingPanel” component.
const MyDataSettings = () => { return ( <PluginDocumentSettingPanel name="my-data" title="My Data"> <TextControl value='' onChange='' /> </PluginDocumentSettingPanel> ); }; if (window.pagenow === 'post') { registerPlugin('mydata', { render: MyDataSettings, icon: null, }); }
And after we add the code above we will see the meta box, but it will do nothing.
To make this field to actually pull the meta data and save the data, we need to use state management functions.
const MyDataSettings = () => { const { meta, meta: { _my_data }, } = useSelect((select) => ({ meta: select('core/editor').getEditedPostAttribute('meta') || {}, })); const { editPost } = useDispatch('core/editor'); const [myData, setMyData] = useState(_my_data); useEffect(() => { editPost({ meta: { ...meta, _my_data: myData, }, }); }, [myData]); return ( <PluginDocumentSettingPanel name="my-data" title="My Data"> <TextControl value={myData} onChange={setMyData} /> </PluginDocumentSettingPanel> ); };
#3 Enqueue Script
I forgot to mention that, we need to enqueue the script. The easiest way is to simply use enqueue_block_editor_assets
action hook because this hook will properly enqueue our script to post edit screen.
add_action( 'enqueue_block_editor_assets', function() { wp_enqueue_script( 'my-data', trailingslashit( plugin_dir_url( __FILE__ ) ) . 'my-data.min.js', [ 'wp-element', 'wp-blocks', 'wp-components', 'wp-editor' ], '0.1.0', true ); } );
And not only that, we need to actually compile the script using webpack, etc.
Yup! building something for WordPress is not going to be as easy as it used to be. We’ll need to create a local dev, install node js, npm, etc.
Download:
To make it easier, I create an example plugin using the code above, you can download it here:
To use this plugin, you’ll need to run CLI command: npm install
And to compile the script: npm run build
.
Let me know if you have question in using/understanding the plugin.
Thanks for giving the plug-in for download it has helped me very much. Thanks again
awesome. glad that the plugin example is useful.
i updated my blog post and add more info in how to use it.
basically use “npm install” to install all dependencies.
and you can use “npm run build” command to compile the JS.
This new way is actually far more better
yes it is. i create an example to explain more about it https://shellcreeper.com/why-use-react-js-to-create-a-meta-box/
super cool!
(but sometimes i miss the simpler old days)
yeah, the typical point of view of a mediocre programmer. Just because it is new and was made by some popular giant company it is better. Where did you get that idea???
The best part is being able to use React instead of plain PHP. Try coding an image picker using the previous methods. Now you can just use MediaUpload from wp.blockEditor. It’s a lot more maintainable and documented.
There is a new command that will do all the setup work for you
npm init @wordpress-block
Hello David!
Can you make a tutorial on how to create block from scratch using webpack?
I did create several videos (youtube), although all in indonesian.
but you can check this base plugin (still in progress, but all is working)
https://github.com/turtlepod/fx-block-base