1

I have a custom block that modifies an Ultimate Add-On Gutenberg Section Block, so that I can define section types, such as exercise and apply some custom formatting.

I noticed on front end my modified block displays JSON above the block. Like this:

<!-- wp:uagb/section {"block_id":"e00ee750-246d-46fd-a034-c6dc37497309","contenttype":"exercise","contenttitle":"here is exercise 1","contentname":"Exercise"} -->

The unmodified block does not display any JSON, so I think it has to do with my modification.

Here is my code:


const { assign } = lodash;
const { addFilter } = wp.hooks;
const { __ } = wp.i18n;

// Enable spacing control on the following blocks
const enableBlockContentTypeAttribute = [
    'uagb/section',
];

// Available spacing control options
const contenttypeControlOptions = [
    {
        label: __( 'None' ),
        value: '',
    },
    {
        label: __( 'Exercise' ),
        value: 'exercise',
    },
    {
        label: __( 'Concept' ),
        value: 'concept',
    },
    {
        label: __( 'Something' ),
        value: 'something',
    },
];

/**
 * Add spacing control attribute to block.
 *
 * @param {object} settings Current block settings.
 * @param {string} name Name of block.
 *
 * @returns {object} Modified block settings.
 */
const addBlockContentTypeAttribute = ( settings, name ) => {
    // Do nothing if it's another block than our defined ones.

    if ( ! enableBlockContentTypeAttribute.includes( name ) ) {
        return settings;
    }
    //console.log('Add content type option');
    // Use Lodash's assign to gracefully handle if attributes are undefined
    settings.attributes = assign( settings.attributes, {
        contenttype: {
            type: 'string',
            default: contenttypeControlOptions[ 0 ].value,
        },
        contenttitle: {
            type: 'string',
            default: '',
        },
        contentname: {
            type: 'string',
            default: contenttypeControlOptions[ 0 ].label,
        },

    } );

    return settings;
};

addFilter( 'blocks.registerBlockType', 'my-mods/attribute/contenttype', addBlockContentTypeAttribute );

const { createHigherOrderComponent } = wp.compose;
const { Fragment } = wp.element;
const { InspectorControls, InnerBlocks } = wp.editor;
const { PanelBody, PanelRow, SelectControl, TextControl } = wp.components;

/**
 * Create HOC to add content type control to inspector controls of block.
 */
const withContentTypeControl = createHigherOrderComponent( ( BlockEdit ) => {
    return ( props ) => {
    // Do nothing if it's another block than our defined ones.
    if ( ! enableBlockContentTypeAttribute.includes( props.name ) ) {
        return (
            <BlockEdit { ...props } />
    );
    }
    //console.log(props.attributes);
    const { contenttype } = props.attributes;
    const { contenttitle } = props.attributes;
    const { contentname } = props.attributes;

    function getContentTitle ( content ) {
        props.setAttributes({contenttitle: content});
    }

    return (
        <Fragment>
        <BlockEdit { ...props } />
<InspectorControls>
    <PanelBody
    title={ __( 'Choose Content Type' ) }
    initialOpen={ true }
        >
        <SelectControl
    label={ __( 'Content Type' ) }
    value={ contenttype }
    options={ contenttypeControlOptions }
    onChange={ ( selectedContentTypeOption ) => {
        var name = contenttypeControlOptions.filter(obj => {
                return obj.value === selectedContentTypeOption
            });
        //console.log(name);
        name = name[0].label;
        //console.log(name);
        props.setAttributes( {
            contenttype: selectedContentTypeOption,
            contentname: name,
        } );
    } }
/>

<TextControl
    label={ __( 'Content Title' ) }
    value={ contenttitle }
    onChange={ ( getContentTitle ) => {
        props.setAttributes( {
            contenttitle: getContentTitle,
        });
    }}
/>

</PanelBody>
    </InspectorControls>
    </Fragment>
);
};
}, 'withSpacingControl' );

addFilter( 'editor.BlockEdit', 'my-mods/with-contenttype-control', withContentTypeControl );



// do something with these attributes - add header to section if exercise type block
const addContentTypeMarkup = ( element, blockType, attributes ) => {
    // Do nothing if it's another block than our defined ones.
    if ( ! enableBlockContentTypeAttribute.includes( blockType.name ) ) {
        return element;
    }
    if ( attributes.contenttitle) {

        // add header with anchor link and class name
        var title_slug = attributes.contenttitle.trim().split(/\s+/).join('-');

        var iconclassbase='contenticon ';
        var iconclass='';
        switch(attributes.contenttype) {
            case 'exercise':
                iconclass =  'fas fa-guitar';
                break;
            case 'concept':
                iconclass = 'fas fa-atom';
                break;
            default:
                iconclass = 'fas fa-atom';
        }
        iconclass = iconclassbase + iconclass;

        return (
            <React.Fragment>
            <div id = {`${title_slug}`} className = {`contenttype-wrapper sometopictype-${attributes.contenttype}`} content-id="" data-id = {`${attributes.block_id}`}>
                <div className = "heading d-flex flex-row">
                    <i className={`${iconclass} fa-7x`}></i>
                    <div className = "col">
                       <div className = "row"><span className="content-name">{attributes.contentname}</span></div>
                       <div className = "row"><h3 dangerouslySetInnerHTML={ { __html: attributes.contenttitle } }></h3></div>
                    </div>
                </div>
                {element}
            </div>
        </React.Fragment>
    )
    } else {
        return element;
    }

};

addFilter( 'blocks.getSaveElement', 'my-mods/add-content-type-markup', addContentTypeMarkup);

Is this JSON output expected? If not, how do I disable that?

thanks, Brian

1
  • If Im not wrong, attribute values are saved in an HTML tag. When the content is actually used in the front end (either in a template file or in a rest route) they are removed. Why do you want to remove them?
    – Alvaro
    Dec 10, 2019 at 2:29

1 Answer 1

0

Yes this is normal for post content, but it should never make it to the frontend if you've processed your content correctly, e.g. by using the_content() to display it. This implies you're displaying raw content that has not gone through the_content filter

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.