8

I am trying to follow the instruction in the Gutenberg Handbook to create a block that can change meta data of a post.

Though when I try to use the setAttributes function from props to save the new data it persisted on the page, but is not actually saved back to the database, as I believe the Handbook states it should if it's source is meta. I must be missing something, but I cannot find a resource to help.

php:

   $args = ...

   register_post_type('event', $args);

   register_meta('event', 'event_location', [
        'show_in_rest' => true,
        'single' => true,
        'type' => 'string'
    ]);

javascript:

registerBlockType('my-plugin/event-location', {
  title: 'Event Location',
  category: 'widgets',

  attributes: {
    location: {
      type: 'string',
      source: 'meta',
      meta: 'event_location'
    }
  },

  edit ({ className, attributes, setAttributes }) {
    const { location } = attributes

    function updateContent (e) {
      setAttributes({ location: e.target.value })
    }

    return el(
      'p',
      { className: className },
      el(
        'input',
        { value: location, onChange: updateContent }
      )
    )
  },

  save () {
    return null
  }
})

2 Answers 2

5

Think I found the answer here. The first argument to register_meta is not post type but object_type, which is in my case should be post rather than taxonomy or comment. The function description, found here, states as of WordPress 4.9.2 the correct parameter is post. Once I switched it everything worked.

register_meta('post', 'event_location', [
    'show_in_rest' => true,
    'single' => true,
    'type' => 'string'
]);

Also, here is a Github issue related to the same problem.

3
  • 1
    It's not quite that register_meta doesn't work for custom post types, it's that object_type and post_type are not the the same thing. Post, Taxonomy and Comment are object types. Page and Post are different post types, but they're both the Post object type. May 11, 2018 at 13:26
  • Thank you @JacobPeattie, I understand. I am new to WordPress and getting used to the nomenclature. I will adjust my answer.
    – lookyhooky
    May 11, 2018 at 23:06
  • 1
    Since 4.9.8 you can use register_post_meta and include the post type, so in your case it would be: register_post_meta('event', 'event_location', /*...*/ )
    – Alvaro
    Nov 24, 2018 at 22:46
0

Here is how you can properly register the custom post meta to make it accessible on the REST API:

/**
 * Registers the custom_post_meta field.
 *
 * @return void
 */
function register_custom_post_meta_field() {
    register_post_meta(
        'post',
        'custom_post_meta',
        [
            'type'         => 'string',
            'show_in_rest' => true,
            'single'       => true,
        ]
    );
}
add_action( 'init', 'register_custom_post_meta_field' );

The, using the approach below you can read and update the post meta value:

import { __ } from '@wordpress/i18n';
import { useSelect, useDispatch } from '@wordpress/data';
import { PanelBody, PanelRow, TextControl } from '@wordpress/components';
import { InspectorControls } from '@wordpress/block-editor';

/**
 * My Custom Block
 */
const MyCustomBlock = () => {
    const META_KEY = 'custom_post_meta'; // This is your custom meta name
    const { editPost } = useDispatch('core/editor');
    const meta = useSelect((select) =>
        select('core/editor').getEditedPostAttribute('meta')
    );
    const { [META_KEY]: customMeta } = meta;

    const onCustomMetaChange = (newValue) => {
        editPost({
            meta: { ...meta, [META_KEY]: newValue },
        });
    };

    return (
        <div>
            <InspectorControls>
                <PanelBody title={__('Settings', 'textdomain')}>
                    <PanelRow>
                        <TextControl
                            label={__('Custom Meta', 'textdomain')}
                            value={customMeta}
                            onChange={onCustomMetaChange}
                        />
                    </PanelRow>
                </PanelBody>
            </InspectorControls>
        </div>
    );
};

For a complete guide, you can follow this tutorial on mine to create, save and update the post meta in the Gutenberg block editor.

Your Answer

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

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