I have created a custom block with innerBlocks, let's call it parent block. I only allow for one kind of block inside that block, let's call it child block using the "allowedBlocks". The simple use-case is when a user wants to add the child block inside the parent block, then it all works fine.
Now here is the problem:
Sometimes one would need to be able to add multiple child blocks inside the parent block next to each other. For that I would love to use the core/colums
block from gutenberg. The problem is, that inside that core/colums
block I also only want to be able to add the child block and no other.
Is there a way to set allowedBlocks for a block inside allowedBlocks? Is there some 'global' way of saying: "all blocks inside of this block can only be one of [..., ..., ...]?"
edit: function( props ) {
return (
<InnerBlocks allowedBlocks={ [ 'my-blocks/child-block', 'core/columns' ] } />
);
}
Now can I specify which blocks can be selected in the InnerBlock core/colums
?
*I know I could just let people add multiple child
inside the parent
, but I want them to be structured and responsive with the colums..
My other idea would be to somehow copy the core/colums
block from gutenberg and modify it, though I don't know where to find it and it wouldn't really be pretty..*
At present, core/column
does not support passing the allowedBlocks property, although you could potentially create your own custom renderAppender for InnerBlocks as a way to limit what blocks can be added.
Below is an alternative approach using 3 custom blocks, templates, child and parent block relationships:
Custom Block:
Contains an InnerBlock
with a template that sets the custom Parent Block as the content of the Column. You could also add other core blocks within the template if desired.
registerBlockType('my-blocks/custom-block', {
...
edit: () => {
const MY_TEMPLATE = [
['core/columns', { columns: 2 }, [
['core/column', {}, [
['my-blocks/parent-block']
]],
['core/column', {}, [
['my-blocks/parent-block']
]],
]]
];
return (
<InnerBlocks
template={MY_TEMPLATE}
templateLock="all"
/>
);
},
save: () => {
return <InnerBlocks.Content />;
}
});
Parent Block:
Contains an InnerBlock
that only accepts the Child Block (or you can also add other core blocks inside allowedBlocks
).
registerBlockType('my-blocks/parent-block', {
...
edit: function({className}) {
return (
<div className={className}>
<InnerBlocks allowedBlocks={['my-blocks/child-block']} />
</div>
);
},
save: function({className}) {
return (
<div className={className}>
<InnerBlocks.Content />
</div>
)
}
})
Child Block: Can only be added to its parent, so will not appear in the Add Block inserter unless its within its Parent Block.
registerBlockType('my-blocks/child-block', {
...
parent: ['my-blocks/parent-block'],
edit: ({ className }) => {
return (
<div className={className}>
<h3>Child Block Content</h3>
</div>
);
},
save: ({ className }) => {
return (
<div className={className}>
<h3>Child Block Content</h3>
</div>
);
},
});
Caveats: The columns will still allow other blocks to be added after the Parent Block unless you create a custom renderAppender to alter this.
The above example should work for your scenario as described by implementing the additional 'Custom Block' to control the allowedBlocks of InnerBlocks
and support core/columns
.
Source code for core/column
and core/columns
: