Pre-requisites
- WordPress Plugin Development
- PhP
- JS/ReactJS
- Hands on experience in Gutenberg block development
Example Scenario
Consider a scenario where a client asks you to develop a functionality. The functinoality includes showing a sub-title of the given page. The sub-title will be content managed and author can decide whether to show/hide that sub-title on the front-end. Hence we need to register 2 meta fields for ‘Page’ post type. This means, we need to show 2 fields in sidebar when page is being edited. Those fields are as follows:
- Sub-title – A simple text field which stores a sub-title associated with page
- Hide sub-title – A boolean checkbox field which will decide to hide/show the sub-title.
Register Custom Meta
First of all, we need to ensure that custom meta is registered for the given post type. This helps in Gutenberg APIs while updating the meta-value on saving the post. You can use register_post_meta function for the same. Find the PhP code below.
<?php
/**
* Function registers the custom meta required for'page' post type.
*
* @return void
*/
function register_post_meta_callback() {
//register meta for 'sub-title'
register_post_meta(
'page',
'custom_page_sub_title', //this will become post-meta key
array(
'show_in_rest' => true,
'single' => true,
'type' => 'string',
'auth_callback' => function() {
return current_user_can( 'edit_posts' );
}
)
);
// Register meta for 'sub-title' show/hide
register_post_meta(
'page',
'custom_page_enable_sub_title', //this will become post-meta key
array(
'show_in_rest' => true,
'single' => true,
'type' => 'boolean',
'auth_callback' => function() {
return current_user_can( 'edit_posts' );
}
)
);
}
add_action('init', 'register_post_meta_callback');
Add the fields in the Gutenberg
Now, it’s the time where you are actually using this registered meta in the Gutenberg editor. Please see the code below:
/**
* Page Subtitle Panel
*/
const {
data: { useSelect, useDispatch },
plugins: { registerPlugin },
element: { useState, useEffect, Fragment },
components: { TextControl },
i18n: { __ },
domReady,
} = wp;
const { PluginDocumentSettingPanel } = wp.editPost || {};
const { ToggleControl } = wp.components;
/**
* Page Subtitle Panel
*/
function PageSubTitle() {
if (!PluginDocumentSettingPanel) {
return null;
}
// Let's fetch the data from existing post meta and set constact values with same meta keys
const {
meta,
meta: {
custom_page_sub_title,
custom_page_enable_sub_title
},
} = useSelect((select) => ({
meta: select('core/editor').getEditedPostAttribute('meta') || {},
}));
const { editPost } = useDispatch('core/editor');
// States/Attributes in terms of holding meta values
const [subTitle, setSubtitle ] = useState( custom_page_sub_title );
const [enableSubTitle, setEnableSubtitle ] = useState( custom_page_enable_sub_title );
//Instantiating the states with post meta values
useEffect(() => {
editPost( {
meta: {
...meta,
custom_page_sub_title: subTitle,
custom_page_enable_sub_title: enableSubTitle,
},
} );
}, [subTitle, enableSubTitle]);
return (
<PluginDocumentSettingPanel
name="page-subtitle-settings-panel"
title={ __( 'Page Subtitle', 'vyawtech' ) }
>
{/* The Subtitle Control - Start */}
<TextControl
value={ subTitle }
onChange={ setSubtitle }
type="string"
placeholder="Sub-title of Page"
label={
__( 'Subtitle', 'vyawtech' )
}
/>
{/* The Subtitle Control - End */}
{/* The hide/show Toggle Control - Start */}
<ToggleControl
checked={ enableSubTitle }
onChange={ ( newEnablePageSubtitle ) => {
setEnableSubtitle( newEnablePageSubtitle );
editPost( {
meta: {
...meta,
[ custom_page_enable_sub_title ]: newEnablePageSubtitle,
},
} );
} }
label={
__( 'Hide Subtitle', 'vyawtech' )
}
/>
{/* The hide/show Toggle Control - End */}
</PluginDocumentSettingPanel>
);
}
if ( 'page' === window.pagenow ) { // Enabling only for 'page' post type
registerPlugin( 'page-subtitle-settings', {
render: PageSubTitle,
icon: false,
});
}
Now register above component in your blocks.js file as shown below
import './sidebar/page-sub-title';
Now register the JS file in block assets so that it will register your Gutenberg block assets.
/**
* Enqueue editor-only JavaScript/CSS for blocks.
*
* @return void
*/
function block_editor_scripts() {
// Editor Scripts
wp_enqueue_script(
'vyawtech-editor',
VYATECH_URL . 'dist/js/blocks.js',
[ 'wp-i18n', 'wp-element', 'wp-blocks', 'wp-components', 'wp-editor', 'wp-dom', 'wp-compose', 'wp-plugins', 'wp-core-data', 'wp-edit-post' ],
VYAWTECH,
true
);
}
add_action( 'enqueue_block_editor_assets', 'block_editor_scripts' );