1

The block itself works fine. The problem is when the post is edited again - the block gives a "This block contains unexpected or invalid content" message. Developer console shows the following error:

blocks.min.js?ver=639e14271099dc3d85bf:10 Block validation: Block validation failed for `create-block/schedule-item` ({name: 'create-block/schedule-item', icon: {…}, keywords: Array(0), attributes: {…}, providesContext: {…}, …}).

Content generated by `save` function:

<div class="wp-block-create-block-schedule-item"><div><div>1</div><div><div>3</div><div>2</div></div></div><div><div><div>1</div><div><div>3</div><div>2</div></div></div><div><div>1</div><div><div>3</div><div>2</div></div></div></div></div>

Content retrieved from post body:

<div class="wp-block-create-block-schedule-item"><div>1</div><div><div>3</div><div>2</div></div></div>

So, basically, the save function apparently generates triple the content, despite it showing fine on frontend.

Here is the block save function:

import { __ } from '@wordpress/i18n';
import { useBlockProps, RichText } from '@wordpress/block-editor';

export default function save({ attributes }) {
    const blockProps = useBlockProps.save({
        className: 'wp-block-create-block-schedule-item',
    });
    const { time, speaker, event, align } = attributes;
    const className = blockProps.className;

    return (<div {...blockProps}>
                <RichText.Content
                    tagName="div"
                    value={time}
                />
                <div>
                    <RichText.Content
                        tagName="div"
                        value={speaker}
                    />
                    <RichText.Content
                        tagName="div"
                        value={event}
                    />
                </div>
    </div>);
}

UPDATE

Raw block markup:

<!-- wp:create-block/schedule-item -->
<div class="wp-block-create-block-schedule-item"><div>13-45</div><div><div>Speakers</div><div>Event</div></div></div>
<!-- /wp:create-block/schedule-item -->

Seems to be in order.

Edit function:

import { __ } from '@wordpress/i18n';
import {
    useBlockProps,
    RichText,
    AlignmentControl,
    BlockControls,
} from '@wordpress/block-editor';
import './editor.scss';

export default function Edit({ attributes, setAttributes }) {
    const blockProps = useBlockProps({
        className: 'wp-block-create-block-schedule-item',
    });
    const { time, event, speaker, align } = attributes;

    const onChangeTime = (newContent) => {
        setAttributes({ time: newContent });
    };
    const onChangeSpeaker = (newContent) => {
        setAttributes({ speaker: newContent });
    };
    const onChangeEvent = (newContent) => {
        setAttributes({ event: newContent });
    };


    const onChangeAlign = (newAlign) => {
        setAttributes({
            align: newAlign === undefined ? 'none' : newAlign,
        });
    };

    return (
        <div {...blockProps}>
            <BlockControls>
                <AlignmentControl value={align} onChange={onChangeAlign} />
            </BlockControls>
            <RichText

                tagName="div"
                value={time}
                onChange={onChangeTime}
                placeholder={__('Time', 'basic-block')}
            />
            <div>
                <RichText

                    tagName="div"
                    value={event}
                    onChange={onChangeEvent}
                    placeholder={__('Event', 'basic-block')}
                />
                <RichText

                    tagName="div"
                    value={speaker}
                    onChange={onChangeSpeaker}
                    placeholder={__('Speaker', 'basic-block')}
                />
            </div>
        </div>
    );
}

And block.json:

{
    "$schema": "https://schemas.wp.org/trunk/block.json",
    "apiVersion": 3,
    "name": "create-block/schedule-item",
    "version": "0.1.0",
    "title": "Schedule Item",
    "category": "widgets",
    "icon": "smiley",
    "description": "Example block scaffolded with Create Block tool.",
    "supports": {
        "html": false
    },
    "textdomain": "schedule-item",
    "editorScript": "file:./index.js",
    "editorStyle": "file:./index.css",
    "style": "file:./style-index.css",
    "attributes": {
        "time": {
            "type": "string",
            "source": "html",
            "selector": "div"
        },
        "speaker": {
            "type": "string",
            "source": "html",
            "selector": "div"
        },
        "event": {
            "type": "string",
            "source": "html",
            "selector": "div"
        },
        "align": {
            "type": "string",
            "default": "none"
        }
    }
}
5
  • 1
    that's not how you use useBlockProps, you can't pass only some of the props you have to pass all of the props of things won't work. Also where is your edit component? Would it not make more sense to wrap the richtext content in a div instead of using tagName? Can you edit your question to include the raw block markup that's been saved to the database as well as your edit component?
    – Tom J Nowell
    Jun 21, 2023 at 16:26
  • 1
    Tom is right, use all useBlockProps on outer HTML element. However, this may also be caused by improper attribute definitions. Please share your block.json or wherever you have attributes defined.
    – Lovor
    Jun 21, 2023 at 16:48
  • Added raw block markup, edit, and block.json. Jun 21, 2023 at 16:54
  • Edited the save function to use entire useBlockProps, but it still keeps returning triplicate. Jun 22, 2023 at 8:56
  • After reading documentation, I guess "selector": "div" could cause this? Not sure. I have another block that has different selectors for the attributes (h4 and span), and it returns in duplicate - number of total attributes. Jun 22, 2023 at 10:36

1 Answer 1

0

The problem was using

   "selector": "div"

for all attributes - it naturally used attributes from every div, hence triplicate.

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.