How can I make a dropdown list control that fetches names of custom posts types? In my project I want to select a post type name and fetch it in drop down selector in my custom Gutenberg Block!.. How can I do this?
If creating a dropdown list (select) for the edit()
function of a Gutenberg block, registered post types can be retrieved with getPostTypes()
via useSelect()
in JavaScript. An example of this is the dropdown in the Query Block to select a Post Type.
Below is a simplified example that uses a <SelectControl/>
to display a list of all viewable post types, and enables a selected postType to be saved the blocks attributes.
block.json
{
...
"attributes": {
"postType": {
"type": "string",
"default": "post"
}
}
}
edit.js
import { useSelect } from '@wordpress/data';
import { store as coreStore } from '@wordpress/core-data';
import { SelectControl } from '@wordpress/components';
import { useBlockProps } from '@wordpress/block-editor';
export default function Edit({ attributes, setAttributes }) {
// postType defined in block.json
const { postType } = attributes;
// useSelect to retrieve all post types
const postTypes = useSelect(
(select) => select(coreStore).getPostTypes({ per_page: -1 }), []
);
// Options expects [{label: ..., value: ...}]
var postTypeOptions = !Array.isArray(postTypes) ? postTypes : postTypes
.filter(
// Filter out internal WP post types eg: wp_block, wp_navigation, wp_template, wp_template_part..
postType => postType.viewable == true)
.map(
// Format the options for display in the <SelectControl/>
(postType) => ({
label: postType.labels.singular_name,
value: postType.slug, // the value saved as postType in attributes
})
);
return (
<div {...useBlockProps()}>
<SelectControl
label="Select a Post Type"
value={postType}
options={postTypeOptions}
onChange={(value) => setAttributes({ postType: value })}
/>
</div>
);
}
The advantage of using JavaScript for the Editor instead of falling back to PHP is you can keep the UI consistent by using Gutenberg controls like <SelectControl/>
.
The Settings Sidebar may be a good place to put your <SelectControl/>
depending on your goal.