Wrap gutenberg block ‘div’ in other elements/extra HTML

When registering a block we indicate: an edit property which defines how the block acts/displays in the editor, and a save property which is responsible for the final HTML of the block.

To modify these two functions from a block we need to use filter hooks. These hooks just need to be included inside a script in the editor.

The getSaveElement filter lets us modify the HTML output of the save property of the block. Using JSX:

const modifySaveHtml = (block, props, attributes) => {
    if (props.name !== "my-plugin/my-block") {
        return block;
    }

    return (
        <div className="transform-container">
            <div className="transform-right">
                <div className="transform-left">
                    <div className="transform-content">{block}</div>
                </div>
            </div>
        </div>
    );
};
wp.hooks.addFilter(
    "blocks.getSaveElement",
    "my-plugin/modifySaveHtml",
    modifySaveHtml
);

Using JS (ES5):

var createElement = wp.element.createElement;

var modifySaveHtml = function(block, props, attributes) {
    if (props.name !== "my-plugin/my-block") {
        return block;
    }

    return createElement(
        "div",
        { className: "transform-container" },
        createElement(
            "div",
            { className: "transform-right" },
            createElement(
                "div",
                { className: "transform-left" },
                createElement("div", { className: "transform-content" }, block)
            )
        )
    );
};
wp.hooks.addFilter(
    "blocks.getSaveElement",
    "my-plugin/modifySaveHtml",
    modifySaveHtml
);

The editor.BlockEdit filter modifies the HTML of the edit property of the block. This might not be necessary if you don’t need to modify the HTML in the editor. Using JSX:

const modifyEditHtml = BlockEdit => {
    return props => {
        if (props.name !== "my-plugin/my-block") {
            return <BlockEdit {...props} />;
        }

        return (
            <div className="transform-container">
                <div className="transform-right">
                    <div className="transform-left">
                        <div className="transform-content">
                            <BlockEdit {...props} />
                        </div>
                    </div>
                </div>
            </div>
        );
    };
};
wp.hooks.addFilter(
    "editor.BlockEdit",
    "my-plugin/modifyEditHtml",
    modifyEditHtml
);

Using JS (ES5):

var createElement = wp.element.createElement;

var modifyEditHtml = function(BlockEdit) {
    return function(props) {
        if (props.name !== "my-plugin/my-block") {
            return createElement( BlockEdit, props );
        }

        return createElement(
            "div",
            { className: "transform-container" },
            createElement(
                "div",
                { className: "transform-right" },
                createElement(
                    "div",
                    { className: "transform-left" },
                    createElement(
                        "div",
                        { className: "transform-content" },
                        createElement(
                            BlockEdit,
                            props
                        )
                    )
                )
            )
        );
    };
};
wp.hooks.addFilter(
    "editor.BlockEdit",
    "my-plugin/modifyEditHtml",
    modifyEditHtml
);

Keep in mind that these filters will be applied to both new instances of the block and old ones. This means that any block which was created previously will show an “invalid content” message. This is because the filter modifies the block definition and it now expects the new HTML which is not there, as the block was created/saved before applying the filter.

When enqueuing your script (from PHP), remember to include the used dependencies. In the above code, wp-hooks package is used and wp-element as well in the non-JSX code.

function my_plugin_enqueue_editor() {

    wp_enqueue_script(
        'my-plugin-script', // name
        'path/to/my-plugin-script.js', // path
        array( // dependencies
            'wp-element',
            'wp-hooks',
        ),
        '1.0.0', // my-plugin version number
        true // enqueue in the footer.
    );

}
add_action( 'enqueue_block_editor_assets', 'my_plugin_enqueue_editor' );

Note: The JS(ES5) code is untested but I think it should work correctly.

Leave a Comment