17

So I am using nested blocks in Wordpress Gutenberg. I am applying a wrapper on my elements that apply a bootstrap container class. Obviously I'd only want that on the outermost blocks, not on the ones inside a nested block.

Is there a way to know if the current block is inside a InnerBlocks Definiton of a parent block? I am currently applying the wrapper inside the blocks.getSaveElement Filter.

Is there a better way to do this?

For context: In previous gutenberg versions there used to be the layout attribute to achieve that, but it has since been removed. I am using Version 3.9.0.

This is a shortened version of my wrapper function:

    namespace.saveElement = ( element, blockType, attributes ) => {
        const hasBootstrapWrapper = hasBlockSupport( blockType.name, 'bootstrapWrapper' );

        if (hasBlockSupport( blockType.name, 'anchor' )) {
            element.props.id = attributes.anchor;
        }
        if (hasBootstrapWrapper) {

            // HERE I NEED TO CHECK IF THE CURRENT ELEMENT IS INSIDE A INNERBLOCKS ELEMENT AND THEN APPLY DIFFERENT WRAPPER

            var setWrapperInnerClass = wrapperInnerClass;
            var setWrapperClass = wrapperClass;
            if (attributes.containerSize) {
                setWrapperInnerClass = wrapperInnerClass + ' ' + attributes.containerSize;
            }
            if (attributes.wrapperType) {
                setWrapperClass = wrapperClass + ' ' + attributes.wrapperType;
            }

            const setWrapperAnchor = (attributes.wrapperAnchor) ? attributes.wrapperAnchor : false;

            return (
                newEl('div', { key: wrapperClass, className: setWrapperClass, id: setWrapperAnchor},
                    newEl('div', { key: wrapperInnerClass, className: setWrapperInnerClass},
                        element
                    )
                )
            );
        } else {
            return element;
        }
    };

wp.hooks.addFilter('blocks.getSaveElement', 'namespace/gutenberg', namespace.saveElement);
1

2 Answers 2

11

getBlockParents will work accurately. You can use getBlockParents with the clientId of the block, getBlockParents will return the all parent blocks id if the current block is under any Blocks. It will return blank if current block is not under any Block

here is a method that you can use:

const innerBlock = "namespace/block-name";
const parentBlocks = wp.data.select( 'core/block-editor' ).getBlockParents(props.clientId); 
const parentAttributes = wp.data.select('core/block-editor').getBlocksByClientId(parentBlocks);

var is_under_inner = false;
for (i = 0; i < parentAttributes.length; i++) {
    if ( parentAttributes[i].name == innerBlock ) {
        is_under_inner = true;
    }
}

//console.log(is_under_inner);
9
+50

you can call getBlockHierarchyRootClientId with the clientId of the block, getBlockHierarchyRootClientId will return the parent block id if the current block is inside innerBlocks and will return the same id if it's root

you can call it like this

wp.data.select( 'core/editor' ).getBlockHierarchyRootClientId( clientId );

additionally, you can define a helper function that you can use in your code

const blockHasParent = ( clientId ) => clientId !== wp.data.select( 'core/editor' ).getBlockHierarchyRootClientId( clientId );

if ( blockHasParent( yourClientId ) { 
    ....
}

2
  • I think the problem is that at the time blocks.getSaveElement runs no clientId has been assigned yet so it looks like it is not possible from inside the filter. Maybe a solution could be achieved trying a work around in some other way.
    – Alvaro
    Commented Sep 8, 2019 at 14:08
  • you can use editor.blockListBlock to run a check inside the block and assign a class or something
    – N. Seghir
    Commented Sep 8, 2019 at 14:39

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.