0

I've followed a tutorial to get a checkbox displaying under the featured image of a post that is being edited using Gutenberg. It's a checkbox to allow the editor to control whether to display the featured image in a single post. This is the first time I've worked in React.

I have it all working as you would expect - the tickbox displays, you can check and uncheck it and it saves ok (as post meta data).

However, the snag is that when you refresh the post editing page, the checkbox is not correctly ticked or unticked. It is always unticked, even when the meta value is true eg it should be ticked.

I'm confident the checkbox setting is being correctly saved. Within my PHP theme templates I can use the meta-data as you would expect. It's there and saving the box checked and unchecked is giving me the values I'd expect when I get the post meta.

There just seems to be something wrong with the way the checkbox is filled in on editing page load.

Here's the javascript I've got:

"use strict"

const el = wp.element.createElement;
const withState = wp.compose.withState;
const withSelect = wp.data.withSelect;
const withDispatch = wp.data.withDispatch;

wp.hooks.addFilter(
    'editor.PostFeaturedImage',
    'extend-block/disable-featured-image-control',
    wrapPostFeaturedImage
);

function wrapPostFeaturedImage( OriginalComponent ) {
    console.log('hello');

    return function( props ) {
        return (
            el(
                wp.element.Fragment,
                {},
                el(
                    OriginalComponent,
                    props
                ),
                el(
                    composedCheckBox
                )
            )
        );
    }
}

class CheckBoxCustom extends React.Component {

    render() {
        const {
            meta,
            updateDisableFeaturedImage,
        } = this.props;

        return (
            el(
                wp.components.CheckboxControl,
                {
                    label: "Disable featured image",
                    help: "If checked, the featured image won't be shown to the reader for single blog posts.",
                    checked: meta.disable_featured_image,
                    onChange:
                        ( value ) => {
                            this.setState( { isChecked: value } );
                            updateDisableFeaturedImage( value, meta );
                        }
                }
            )
        )
    }
}

const composedCheckBox = wp.compose.compose( [
    withState( ( value ) => { isChecked: value } ),
    withSelect( ( select ) => {
        const currentMeta = select( 'core/editor' ).getCurrentPostAttribute( 'meta' );
        const editedMeta = select( 'core/editor' ).getEditedPostAttribute( 'meta' );
        return {
            meta: { currentMeta, editedMeta },
        };
    } ),
    withDispatch( ( dispatch ) => ( {
        updateDisableFeaturedImage( value, meta ) {
            meta = {
                meta,
                disable_featured_image: value,
            };
            dispatch( 'core/editor' ).editPost( { meta } );
        },
    } ) ),
] )( CheckBoxCustom );

And the meta data is being set as follows:

function post_register_meta() {
    register_meta(
        'post',
        'disable_featured_image',
        array(
            'show_in_rest' => true,
            'single'       => true,
            'type'         => 'boolean',
        )
    );
}
0

I think the problem might be that the spread operator is missing in a couple of places. This line:

return {
     meta: { currentMeta, editedMeta },
};

in withSelect should be:

return {
     meta: { ...currentMeta, ...editedMeta },
};

This makes the meta object be a copy of currentMeta (have all the same properties and values), but overwrites them with any that are present in editedMeta.

There is a mixture of ES5 and ES6 syntax in the code, so if that doesn't work you can achieve the same thing with ES5 by doing:

return {
     meta: Object.assign( {}, currentMeta, editedMeta ),
};

Also in withDispatch the same technique is being used to update the meta object, so that will need changing to:

       updateDisableFeaturedImage( value, meta ) {
            meta = {
                ...meta,
                disable_featured_image: value,
            };

I've not tested this so there might be other problems, but hopefully, this will get you a step closer. Good luck!

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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