Wrapping blocks in WordPress’ Gutenberg editor

April 18, 2019

One of the biggest advantage of using the new Gutenberg editor is that you can repeat blocks. And that you can repeat blocks whilst wrapping them in other blocks. For infinite recursion.

I’ve previously written a quick-guide on setting up custom blocks in WordPress’ Gutenberg editor here.

The basic gist of what we want to accomplish is that we want to have an active block area within one of our custom blocks. After looking through some of the Gutenberg source-code, I found the built-in inner-blocks component. Which is exactly what we want to use.

You won’t really be needing any backend for this. The only gotcha is that the repeated blocks will appear in the $content variable in your render_callback that’s sent to the register_block_type function.

Implementation

So let’s look at a really simple implementation – a custom gutenberg block – which only supports repetition of the built in core/image blocks.

const { registerBlockType } = wp.blocks;
const { InnerBlocks } = wp.editor;

// List of blocks that we allow to be used inside our custom block
const ALLOWED_BLOCKS = [ 'core/image' ];

export default registerBlockType(
    'my-block/image-list-block',
    {
        title: 'Image list',
        description: 'Repeat a list of images',
        category: 'common',
        icon: 'universal-access-alt',
        keywords: [ ],
        attributes: {},
        edit: props => {
            return [
<div>
                    <InnerBlocks
                        allowedBlocks={ ALLOWED_BLOCKS }
                    />
                </div>

            ];
        },
        save( { attributes } ) {
            // This is key, the output of this method is what'll be stored as the
            // content on our block.
            return (
                <InnerBlocks.Content />
            );
        },
    },
);

There’s more options that you can send in to the inner-block, like template locking, initial templates, etc. But this is all you need to get started with repeating your own blocks.

This is how the component is stored in the database. Our own block wraps around two core/image blocks, with their own metadata.

<!-- wp:my-block/image-list-block -->
<!-- wp:image {"id":143} -->
<figure class="wp-block-image"><img src="http://example.local/wp-content/uploads/2019/04/first-image-1024x683.jpg" alt="" class="wp-image-143"/></figure>
<!-- /wp:image -->

<!-- wp:image {"id":142} -->
<figure class="wp-block-image"><img src="http://example.local/wp-content/uploads/2019/04/second-image-1024x683.jpg" alt="" class="wp-image-142"/></figure>
<!-- /wp:image -->
<!-- /wp:my-block/image-list-block -->

When this renders out to the frontend, it’ll unwrap by first rendering the inner-children, working its way outwards.

Conclusion

And that’s it, there’s not much more to it. Repeating or enclosing blocks like this is an awesome way of building out reusable blocks.

One concrete example would be a list of team members. You’d have a specific my-block/person-block representing a single person, which can be repeated inside of a my-block/team-block.

By separating these blocks in to two separate entities, will give you more flexibility in the future to reuse the blocks for other things. For example, the my-block/person-block could potentially be used as a contact block, or something similar.

Tags