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

  • 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 '19 at 2:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.