0

I need to build a really simple block with just one select field. This select field should be populated with the titles/ids of posts of a specific post type. Once a user selects one post from this select field, its id should be saved in a particular attribute.

I have most of the code written, I just need to complete the part that populates the select field with all the posts of a specific post type published in my site.

I know that I must use the wp.data.select( 'core' ).getEntityRecords() selector somewhere, but I have no idea how to start. Any help would be appreciated.

export const settings = {
    title: __( 'Post Selection', 'plugin-domain' ),
    category: 'layout',
    attributes: {
        id: {
            type: 'integer',
            default: 0,
        },
    },

    edit: props => {
        const attributes = props.attributes;

        const setID = value => {
            props.setAttributes( { id: value } );
        };

        return (
            <div>
                <SelectControl
                    label={ __( 'Select a post:', 'plugin-domain' ) }
                    value={ attributes.id }
                    options={ ... fill with all post titles/ids of a specific post type ... }
                    onChange={ setID }
                />
            </div>
        );

    },

    save: props => { ... omitted for brevity ... }

};

registerBlockType( 'my/postselectblock', settings );

1 Answer 1

2

I managed to come up with a solution myself. To get a list of posts of a specific post type one must wrap the wp.data.select( 'core' ).getEntityRecords() selector inside the withSelect higher order component, which is a function that provides props to a component using selectors. Then, we can populate a SelectControl with this data.

export const settings = {
    title: __( 'Post Selection', 'plugin-domain' ),
    category: 'common',
    attributes: {
        id: {
            type: 'integer',
            default: 0,
        },
    },

    edit: withSelect( ( select ) => {
        return {
            posts: select( 'core' ).getEntityRecords( 'postType', 'my_custom_post_type', { per_page: -1 } )
        };
    } )
    ( props => {
        const { attributes, className } = props;

        const setID = value => {
            props.setAttributes( { id: Number( value ) } );
        };

        if ( ! props.posts ) {
            return __( 'Loading...', 'plugin-domain' );
        }

        if ( props.posts.length === 0 ) {
            return __( 'No posts found', 'plugin-domain' );
        }

        var options = [];
        options.push( {
            label: __( 'Choose a post...', 'plugin-domain' ),
            value: ''
        } );

        for ( var i = 0; i < props.posts.length; i++ ) {
            options.push( {
                label: props.posts[i].title.raw,
                value: props.posts[i].id
            } );
        }

        return (
            <Placeholder
                key='post-selection-block'
                icon='admin-post'
                label={ __( 'Post Selection Block', 'plugin-domain' ) }
                className={ className }>
                    <SelectControl
                        label={ __( 'Select a post:', 'plugin-domain' ) }
                        value={ attributes.id }
                        options={ options }
                        onChange={ setID }
                    />
            </Placeholder>
        );

    } ),

    save( { attributes } ) {
        ... omitted for brevity ...
    },

};

registerBlockType( 'my/postselectblock', settings );

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.