WordPress / gutenberg

The Block Editor project for WordPress and beyond. Plugin is available from the official repository.
https://wordpress.org/gutenberg/
Other
10.46k stars 4.18k forks source link

Is it possible to store InnerBlocks content as post meta field? #48179

Closed giannis-koulouris-bb closed 1 year ago

giannis-koulouris-bb commented 1 year ago

I'm creating a custom block for a 'Testimonial' CPT where user will have to fill the persons Name, Role & the Testimonial Text. This custom block is added automatically to each new post via Block Template and it's locked so the user can't add other blocks to that post.

function bb_testimonial_cpt_gutenberg_template()
{
  $post_type_object = get_post_type_object('testimonial');
  $post_type_object->template = array(
    array('bb/testimonial-input-block'),
  );

  $post_type_object->template_lock = 'all'; // lock template
}
add_action('init', 'bb_testimonial_cpt_gutenberg_template');

Untill now for rich-text fields I was using the RichText component, with the multiline="p" attribute so user can add multiple paragraphs, now this attribute is deprecated and prompts me to use innerBlocks instead.

I'm looking for a way to store this block's innerBlocks in the testimonial_text meta field. I know I could use the post content for that purpose, but I want to constrain the user's ability to add other blocks and also to create a nice interface where user can fill these 3 easily using the Gutenberg components instead of native custom fields.

This is the code I'm using to register that block. Any help would be much appreciated.

registerBlockType('bb/testimonial-input-block', {
  title: 'Testimonial Input',
  icon: 'testimonial',
  category: 'bb-meta-blocks',
  apiVersion: '2',
  supports: {
    multiple: false, // Use the block just once per post
    inserter: false, // Disable adding block via the inserter
  },

  edit: props => {
    const blockProps = useBlockProps();
    const postType = useSelect(
      (select) => select('core/editor').getCurrentPostType(),
      []
    );

    const [meta, setMeta] = useEntityProp('postType', postType, 'meta');
    const { testimonial_role, testimonial_text } = meta;

    const ALLOWED_BLOCKS = ['core/heading', 'core/paragraph', 'core/list'];

    const innerBlocksProps = useInnerBlocksProps({ className: "testimonial-text-input" }, {
      allowedBlocks: ALLOWED_BLOCKS,
      templateLock:false,
    });

    return (
      <div {...blockProps}>
        <RichText
          tagName="div"
          value={testimonial_role}
          allowedFormats={[]}
          placeholder='Testimonial Role'
          onChange={(newValue) => setMeta({ ...meta, testimonial_role: newValue })}
        />
        <div {...innerBlocksProps}></div>
      </div>
    );
  },

  // No information saved to the block.
  // Data is saved to post meta via the hook.
  save: () => {
    return null;
  },
});
tomdevisser commented 1 year ago

Hi @giannis-koulouris-bb,

First of all, please know these GitHub Issues are not meant for personal support, this is where people raise bugs, so when you're using it for your personal issues you're holding up developers from fixing real bugs for the rest of the world using Gutenberg. That being said, I will try to point you in the right direction, assuming you didn't know this is not the right place to get support.

In your block's props there's a clientId. With this you can get the InnerBlocks' content from the data store and then do with it as you please. Read more about the data stores here.

Screenshot 2023-02-17 at 2 18 15 PM

Would you please close this issue? 🙂

giannis-koulouris-bb commented 1 year ago

Hey @thomasdevisser, your right, maybe that wasn't the right place to post my issue. Thank you for your help, I will close it now.