-
-
Save gaambo/633bcd83a9596762218ffa65d0cfe22a to your computer and use it in GitHub Desktop.
import { Fragment } from "@wordpress/element"; | |
import { InnerBlocks } from "@wordpress/editor"; | |
/** | |
* Changes the edit function of an ACF-block to allow InnerBlocks | |
* Should be called like this on `editor.BlockEdit` hook: | |
* ` addFilter("editor.BlockEdit", "namespace/block", editWithInnerBlocks("acf/block-name"));` | |
* | |
* @param {string} blockName the name of the block to wrap | |
* @param {object} innerBlockParams params to be passed to the InnerBlocks component (like allowedChildren) | |
*/ | |
const editWithInnerBlocks = ( | |
blockName, | |
innerBlockParams, | |
append = true, | |
hideBlockEdit = false | |
) => BlockEdit => props => { | |
if (props.name !== blockName) { | |
return <BlockEdit {...props} />; | |
} | |
if (append) { | |
return ( | |
<Fragment> | |
{!hideBlockEdit && <BlockEdit {...props} />} | |
<InnerBlocks {...innerBlockParams} /> | |
</Fragment> | |
); | |
} | |
// put before block edit | |
return ( | |
<Fragment> | |
<InnerBlocks {...innerBlockParams} /> | |
{!hideBlockEdit && <BlockEdit {...props} />} | |
</Fragment> | |
); | |
}; | |
/** | |
* Changes the save function of an ACF-block to allow InnerBlocks | |
* Should be called like this on `blocks.getSaveElement` hook: | |
* `addFilter("blocks.getSaveElement", "namespace/block", saveWithInnerBlocks("acf/block-name"));` | |
* | |
* @param {string} blockName the name of the block to wrap | |
*/ | |
const saveWithInnerBlocks = blockName => (BlockSave, block) => { | |
if (typeof block === "undefined") { | |
return BlockSave; | |
} | |
if (block.name !== blockName) { | |
return BlockSave || block.save; | |
} | |
return ( | |
<div> | |
<InnerBlocks.Content /> | |
</div> | |
); | |
}; | |
export { editWithInnerBlocks, saveWithInnerBlocks }; |
@terence1990 really cool and thank you for your work. It works like a charm :-)
Please note, since the latest Gutenberg version the inner blocks container selector was changed from .editor-inner-blocks
to .block-editor-inner-blocks
.
@gaambo and @terence1990 any idea how we can solve it with multiple inner blocks like different columns inside an ACF block and each column can include different inner blocks? :-)
@gaambo and @terence1990 an other issue is, if you use the same block multiple times the selector class "js-inner-blocks" works only for on block, but not for multiple blocks. The selector class needs a unique identifier e.g. the ACF block id, but I don't know how I can get the ACF block id inside the react code. Is there a filter of ACF which provides the block id?
Thanks for your inputs - I'll have to test & play with WordPress 5.4 in the following days and hopefully I can come up with an solution or at least an idea - I'll let you know :)
@CreativeDive Regarding multiple inner blocks: AFAIK there's still no way to include multiple innerBlocks in a block (even via React) - so we'd have to gez creative here and a solution should be future-compatible.
Right now the only thing that comes into my mind is building multiple blocks:
- "Container"/"Wrapper" block which allows only the following "Slots" block
- "Slots" block which can only be inserted to certain parents and only allows single blocks
- Single block which can only be inserted in the slots block.
Depending on the use case that's not really easiert then using the core group + columbs blocks.
For accordions I solved it like this:
Accordion-ACF-Block which only allows Accordion-Iten Blocks as innerBlocks.
FYI: ACF 5.9 will support innerBlocks: https://www.advancedcustomfields.com/blog/acf-5-9-exciting-new-features/
@gaambo: Very exciting ;-)
@terence1990 that looks great. I also thought about having a
supports
flaginnerBlocks
and den do everything automatically (also the supported innerblocks etc.). Thanks for your snippet :)