Restricting PluginDocumentSettingPanel by post type

Now that the PluginDocumentSettingPanel is in WordPress core, we can add our own panels to the Document Settings panel using the registerPlugin function.

const { registerPlugin } = wp.plugins;
const { PluginDocumentSettingPanel } = wp.editPost;

const MyCustomSideBarPanel = () => (
    <PluginDocumentSettingPanel
        name="my-custom-panel"
        title="My Custom Panel"
    >
        Hello, World!
    </PluginDocumentSettingPanel>
);
registerPlugin( 'my-custom-panel', {render: MyCustomSideBarPanel } );

The above code will insert a new Panel in the Document Sidebar with the title of My Custom Panel ” and will display “Hello, World!” as it’s content. If we want this panel to appear on every post type registered, then we’re done but what if we want to restrict this panel to just a single post type?

To do this, we’ll need to know what the current post type is and then only render this SlotFill if it’s the correct post type. So how can we do this?

Two Solutions

In order to get access to the post type, we will need to leverage wp.data.select() function. This can be done directly as seen above it’s better to use either the withSelect Higher-Order Component or the newer useSelect Hook. We’ll look at both here.

withSelect

withSelect is a Higher Order Component that will allow us to give our custom component some new functionality.

const CustomSideBarPanelwithSelect = withSelect( ( select ) => {
    return {
        postType: select( 'core/editor' ).getCurrentPostType(),
    };
} )( MyCustomSideBarPanel );

Examining the above, we can see that withSelect takes a function as a parameter that returns a props object contain items that will be merged with the Component that is being wrapped, MyCustomSideBarPanel, and returns the augmented component. Which we’re callingCustomSideBarPanelWithSelect.

So with that in mind, we need to update MyCustomSideBarPanel to accept the new postType props being passed to it:

const MyCustomSideBarPanel = ( { postType } ) => (
    <PluginDocumentSettingPanel
        name="my-custom-panel"
        title="My Custom Panel"
    >
        Hello, World!
    </PluginDocumentSettingPanel>
);

Once we have this in place, we just need to update the logic inside the Component to look for the proper post type before rendering.

const MyCustomSideBarPanel = ( { postType } ) => {

	if ( 'post-type-name' !== postType ) {
		return null;
	}

	return(
            <PluginDocumentSettingPanel name="my-custom-panel" title="My Custom Panel">
		Hello, World!
	    </PluginDocumentSettingPanel>
	);
}

Full Code:

const { registerPlugin } = wp.plugins;
const { PluginDocumentSettingPanel } = wp.editPost
const { withSelect } = wp.data;

const MyCustomSideBarPanel = ( { postType } ) => {

	if ( 'post-type-name' !== postType ) {
		return null;
	}

	return(
		<PluginDocumentSettingPanel
			name="my-custom-panel"
			title="My Custom Panel"
		>
			Hello, World!
		</PluginDocumentSettingPanel>
	);
}

const CustomSideBarPanelwithSelect = withSelect( select => {
	return {
		postType: select( 'core/editor' ).getCurrentPostType(),
	};
} )( MyCustomSideBarPanel);


registerPlugin( 'my-custom-panel', { render: CustomSideBarPanelwithSelect } );

useSelect

The useSelect hook is a newer addition to Gutenberg and greatly simplifies the code required to set up access to the post type. The only change we need to make to our existing component is to add the check inside:

const { registerPlugin } = wp.plugins;
const { PluginDocumentSettingPanel } = wp.editPost
const { useSelect } = wp.data;

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

	if ( 'post-type-name' !== postType ) {
		return null;
	}

	return(
		<PluginDocumentSettingPanel
			name="my-custom-panel"
			title="My Custom Panel"
		>
			Hello, World!
		</PluginDocumentSettingPanel>
	);
}
registerPlugin( 'my-custom-panel', { render: MyCustomSideBarPanel } );

Similar to withSelect, useSelect takes a function as a parameter that returns whatever you want to be stored. In our case, we just need the result of calling select('core/editor').getCurrentPostType().

Hope this helps!

Leave a Reply

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