Gutenberg Blocks - Change EDIT part of the block using editor.BlockEdit filters. How to change the markup?

wordpress.stackexchange https://wordpress.stackexchange.com/questions/386386

  •  26-04-2021
  •  | 
  •  

Question

I want to edit the core/heading block so it changes it's markup from <h1>Hello world</h1> to <h1><span>Hello world</span></h1>. Note the <span> element in between.

The code below does not work as it should. It adds the span outside the block, as a wrapper. <span><h1>Hello world</h1></span>. Is there a way to alter the <BlockEdit/> element? And goal should be to not add the span element into the content field.

Thought, if altering the edit part, should I also mirror this on the save part?

const { createHigherOrderComponent } = wp.compose;
const { Fragment } = wp.element;
const { InspectorControls } = wp.blockEditor;
const { PanelBody } = wp.components;

const withInspectorControls =  createHigherOrderComponent( ( BlockEdit ) => {

    return ( props ) => {

        if (props.name !== "core/heading") {
            return <BlockEdit { ...props } />;
        }
        
        return (
            <Fragment>
                <span>
                    <BlockEdit { ...props } />
                </span>
            </Fragment>
        );
    };
}, "withInspectorControl" );

wp.hooks.addFilter( 'editor.BlockEdit', 'my-plugin/with-inspector-controls', withInspectorControls );

Was it helpful?

Solution

Unfortunately there is now way to alter the markup of an existing block apart from wrapping it in additional markup:

It receives the original block BlockEdit component and returns a new wrapped component. Source: https://developer.wordpress.org/block-editor/developers/filters/block-filters/#editor-blockedit

To achieve what you want in the editor currently the only way would be to create your own version of the heading block replacing the core one.

But what you can do, and probably is the better way to do it anyway since you leave the default markup in the DB in place, is change the markup on render using the render_block filter.

You can then either use regular expressions or something more solid like a DOM Parser (e.g. https://github.com/wasinger/htmlpagedom) to alter the markup on output any way you like.

<?php
add_filter('render_block', function ($blockContent, $block) {

    if ($block['blockName'] !== 'core/heading') {
        return $blockContent;
    }           

    $pattern = '/(<h[^>]*>)(.*)(<\/h[1-7]{1}>)/i';
    $replacement = '$1<span>$2</span>$3';
    return preg_replace($pattern, $replacement, $blockContent);

}, 10, 2);

I've also written a blog post on various ways to configure Gutenberg that also covers the render_block filter and some reasoning around it in case you want to dig deeper.

OTHER TIPS

It is possible to do just that by using blocks.registerBlockType filter. For a detailed explanation, refer to this article by Jim Schofield

However, instead of calling default edit and save functions wrapped in custom code (like in the article), do not call them, just provide your own code.

Licensed under: CC-BY-SA with attribution
Not affiliated with wordpress.stackexchange
scroll top