5

As referenced in this issue ( https://github.com/WordPress/gutenberg/issues/33374) I want my custom block's innerblocks to have the default layout and alignment controls Like the layout toggle for the Group block, but baked in.

It was answered, but I can't figure out the code:

you can do it by providing a layout to inner blocks, that said, the feature is still experimental at the moment, you should be able to pass __experimentalLayout ={ { contentSize: '800px', wideSize: '1000px' } } to your inner blocks, you can also pass __experimentalLayout ={ { inherit: true } } to your inner blocks as well to inherit whatever layout is defined.

My code

export default function Edit() {
    return (
        <div {...useBlockProps()}>
            <InnerBlocks />
        </div>
    );
}

This doesn't work

export default function Edit() {
    return (
        <div {...useBlockProps()}>
            <InnerBlocks __experimentalLayout ={ { inherit: true } } />
        </div>
    );
}

Does it go in supports in block.json?

What I'm trying to do

This issue explains the custom block I'm trying to make. Very simple! But I need innerblocks to have alignment control and you lose that on innerblocks when you use theme.json. https://github.com/WordPress/gutenberg/issues/36465

Updated code

I added this to the block.json, which adds the toggle for default layout, but the innerblocks still don't have full/wide alignment control. Not sure how to do that, but halfway there.

    "supports": {
    "__experimentalLayout": {
      "contentSize": "800px",
      "wideSize": "1000px",
            "inherit": true
    }
    },

Updated code from stokeman's answer

block.json

{
    "apiVersion": 2,
    "name": "mbp/details",
    "version": "0.1.0",
    "title": "Details",
    "category": "design",
    "icon": "heart",
    "supports": {
        "align": ["full"],
        "__experimentalLayout": {
        "allowSwitching": false,
        "default": {
                "inherit": true
        }
}
    },
        "attributes": {
    "align": {
            "type": "string",
            "default": "full"
        }
    },
    "textdomain": "mobilebevpros",
    "editorScript": "file:../../../../build/details.js"
}

edit.js

import { __ } from "@wordpress/i18n";
import {
    useBlockProps,
    useSetting,
    InnerBlocks,
} from "@wordpress/block-editor";

export default function Edit() {
    const defaultLayout = useSetting("layout") || {};
    return (
        <div {...useBlockProps()}>
            <InnerBlocks __experimentalLayout={defaultLayout} />
        </div>
    );
}
0

2 Answers 2

3

You're pretty close. Specifying layout details in block.json should nest inside a "default" property. Doing so will have the Layout panel display accordingly but there's more to it than that.

If you want the default layout for the block, there is no need to add contentSize or wideSize. Here is the layout config I'd recommend (within the block json supports property):

        "__experimentalLayout": {
            "allowSwitching": false,
            "default": {
                "inherit": true
            }
        }

That will make the Layout panel in the block’s sidebar/inspector simplified to only show the inherit toggle (on by default) and not the size inputs.

Even though the block.json specifies that layout should inherit by default, the default needs to be manually retrieved and passed to InnerBlocks in the edit component:

import {
    useBlockProps, // already in use from example
    useSetting     // new bit
} from '@wordpress/block-editor';

export default function Edit() {
    const defaultLayout = useSetting( 'layout' ) || {};
    return (
        <div {...useBlockProps()}>
            <InnerBlocks __experimentalLayout={ defaultLayout } />
        </div>
    );
}

Besides that the block must be registered on the server but I take it that's already being done.

I'm not sure I wouldn't look for alternative solutions since the experimental nature of the API means it will need some care to not break in future updates to the site.

5
  • Thank you — I just tried out your code, but the inner blocks still don't have align options on the toolbar. And the layout toggle isn't on by default. I'll add my code to my question. Maybe I'm missing something. Thank you!
    – Elizabeth
    Commented Dec 2, 2021 at 16:53
  • I added the block.json and edit.js to my question. Seems like I have exactly what you have no?
    – Elizabeth
    Commented Dec 2, 2021 at 16:56
  • Yes, that looks right. I just tested on the version of Gutenberg that ships with WP 5.8.2 and this wasn't working. I'd originally been testing with a newer build of the Gutenberg plugin. If you aren't using the plugin or its latest version already, installing/upgrading it may get this working.
    – stokesman
    Commented Dec 3, 2021 at 18:04
  • Ahhh, I see. I'm creating a production site for a client so I can't use the Gutenberg plugin unfortunately. Frustrating! Thanks for your help — appreciated.
    – Elizabeth
    Commented Dec 3, 2021 at 19:00
  • I'd like to add to this answer that, even with these settings, and with the layout panel showing the toggle on to inherit, the block itself still had it's contents not inheriting until I toggled it off and back on again. I was able to fix this, however, by adding a layout attribute to the block: "layout": { "type": "object", "default": { "type": "default", inherit": true } }
    – cr0ybot
    Commented Jan 19, 2022 at 19:53
0

Based on what I understand of what you're trying to do, I think it might be best accomplished by registering a block variation for the Group block. It can preset the padding and inheritance of the default layout and has options that can make it appear as its own separate block. This example creates one that will show up in the inserter as "Dat Section" and has some preset padding and a custom class:

wp.blocks.registerBlockVariation(
    'core/group',
    {
        name:'dat-section',
        title: 'Dat Section',
        isActive: (blockAttributes, vAttributes) =>
            blockAttributes.className
                .includes(vAttributes.className),
        attributes: {
            className: 'dat-section',
            layout: {
                inherit: true,
            },
            style:{
               spacing:{
                   padding: { top: '25px', bottom:'55px' }
               }
            }
        },
    }
);

There are more options too. You can set a different icon and description or specify innerBlocks to have it insert with some blocks nested already.

1
  • that's the option I'm currently going with, but I'm frustrated by the limitations of not being able to add inspector controls components. For example, I don't want my client to have the padding controls. I want a select control where they choose from set padding choices. For some blocks, the group variation works. For others, not so much. I'm not sure if I'm missing a way to add that stuff? But I don't think I can. Thank you for this suggestion!
    – Elizabeth
    Commented Dec 4, 2021 at 0:49

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.