Skip to content

Instantly share code, notes, and snippets.

@gaambo
Last active December 29, 2021 18:11
Show Gist options
  • Star 15 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gaambo/633bcd83a9596762218ffa65d0cfe22a to your computer and use it in GitHub Desktop.
Save gaambo/633bcd83a9596762218ffa65d0cfe22a to your computer and use it in GitHub Desktop.
ACF Block with Innerblocks
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 };
@CreativeDive
Copy link

@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? :-)

@CreativeDive
Copy link

CreativeDive commented Mar 30, 2020

@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?

@gaambo
Copy link
Author

gaambo commented Apr 1, 2020

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 :)

@gaambo
Copy link
Author

gaambo commented Apr 1, 2020

@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.

@gaambo
Copy link
Author

gaambo commented May 29, 2020

@CreativeDive
Copy link

@gaambo: Very exciting ;-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment