1

I am building a gutenberg block plugin and I got stuck on simple two-field structure. The issue is that the save function works properly but something is wrong with the edit function. When I reload page I get this error: 'This block contains unexpected or invalid content.'

And in browser console I get the following error:

Block validation: Expected text lkjhlkjhlkjh, saw poiupoiupoiu. Block validation: Block validation failed for protex-contact/g-block ( Object { name: "protex-contact/g-block", title: "Protex konakt", icon: {…}, category: "common", attributes: {…}, edit: edit(), save: save() } ).

Expected:

<div class="wp-block-protex-contact-g-block"><p class="prtx_contact_name">lkjhlkjhlkjh</p><p class="prtx_contact_address">lkjhlkjhlkjh</p></div>

Actual:

<div class="wp-block-protex-contact-g-block"><p class="prtx_contact_name">lkjhlkjhlkjh</p><p class="prtx_contact_address">poiupoiupoiu</p></div>

Here is my JS:

    const { __ } = wp.i18n;
    var el = wp.element.createElement,
        registerBlockType = wp.blocks.registerBlockType,
        RichText = wp.editor.RichText;
    registerBlockType( 'protex-contact/g-block', {
        title: __( 'Protex konakt', 'protex-contact-domain' ),
        icon: 'id',
        category: 'common',
        attributes: {
            content: {
                type: 'string',
                source: 'html',
                selector: 'p',
            },
            content2:{
                type: 'string',
                source: 'html',
                selector: 'p',
            },
        },

        edit: function( props ) {
            var content = props.attributes.content,
            content2 = props.attributes.content2;

            function onChangeContent( newContent ) {
                props.setAttributes( { content: newContent } );
            }

            function onChangeContent2 ( newContent2 ){
                props.setAttributes( { content2: newContent2 } );
            }

            return el ( 'div', { className: props.className }, 
                el(
                RichText,
                {
                    tagName: 'p',
                    className: 'prtx_contact_name',
                    onChange: onChangeContent,
                    value: content,
                }
                ),
                el(
                RichText,
                {
                    tagName: 'p',
                    className: 'prtx_contact_address',
                    onChange: onChangeContent2,
                    value: content2,
                }
                ),
            );
        },

        save: function( props ) {
            var content = props.attributes.content;
            var content2 = props.attributes.content2;
            return el ( 'div', { className: props.className },
                el( RichText.Content, {
                    tagName: 'p',
                    className: 'prtx_contact_name',
                    value: content,
                } ),
                el( RichText.Content, {
                    tagName: 'p',
                    className: 'prtx_contact_address',
                    value: content2,
                } ),
            );
        },
    } );
1

The problem is with your selectors:

attributes: {
    content: {
        type: 'string',
        source: 'html',
        selector: 'p',
    },
    content2:{
        type: 'string',
        source: 'html',
        selector: 'p',
    },
},

You're only using p for both attributes.

When the block looks at the saved HTML to validate it, it checks to see if the value of the selectors matches the value of the attribute. If it doesn't then the validation fails.

So given this HTML:

<div class="wp-block-protex-contact-g-block">
    <p class="prtx_contact_name">lkjhlkjhlkjh</p>
    <p class="prtx_contact_address">poiupoiupoiu</p>
</div>

It checks the value for content by looking for p, and it finds lkjhlkjhlkjh, which is the content of the first p tag. This is also the saved value for content, so things are looking good so far.

Then it looks for the value for content2 by also looking at the first p tag, since that's the selector, and this also finds lkjhlkjhlkjh. However, the block thinks that the value for content2 is supposed to be poiupoiupoiu, so it thinks that the HTML has been saved incorrectly.

So you need to make sure that your selectors can be used to find the correct value in the HTML. You can do this by using the classes you're already using on those paragraphs:

attributes: {
    content: {
        type: 'string',
        source: 'html',
        selector: 'p.prtx_contact_name',
    },
    content2:{
        type: 'string',
        source: 'html',
        selector: 'p.prtx_contact_address',
    },
},

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.