Best practices for CPT without using an editor [closed]

I have used the custom block option quite extensively. I enable the editor for the custom post type, but use a custom template with template_lock set to true:

'template' => array(
    array('pb/custom-block-name'),
),
'template_lock' => true

Then I use the allowed_block_types_all filter to only allow that custom block for the post type:

function pb_allowed_block_types($allowed_block_types, $block_editor_context) {
    if (!$block_editor_context->post || $block_editor_context->post->post_type !== 'custom_post_type') {
        return $allowed_block_types;
    }

    return array(
        'pb/custom-block-name',
    );
}
add_filter('allowed_block_types_all', 'pb_allowed_block_types', 10, 2);

Finally, I use custom post meta within the custom block using useEntityProp to get and set the meta:

import { __ } from '@wordpress/i18n';
import { useSelect } from '@wordpress/data';
import { useEntityProp } from '@wordpress/core-data';

const Edit = (props) => {
    const postType = useSelect((select) => (
        select('core/editor').getCurrentPostType()
    ));

    const [meta, setMeta] = useEntityProp('postType', postType, 'meta');

    return (
        <TextControl
            label={ __('Label', 'pb') }
            value={ meta._pb_meta_slug }
            onChange={ (value) => setMeta({_pb_meta_slug: value}) }
        />
    );
};

Make sure you use register_post_meta to register all your post meta for the custom post type or it won’t save:

register_post_meta('custom_post_type', '_pb_meta_slug', array(
    'type' => 'string',
    'single' => true,
    'auth_callback' => function() {
        return current_user_can('edit_posts');
    },
    'show_in_rest' => true,
));

Leave a Comment