Introduction
Welcome to Day 21 of the Gutenberg development series! In today’s article, we’ll cover nested blocks, a powerful feature that allows you to structure content by placing blocks inside other blocks. This is useful for creating complex layouts, such as columns, grids, or grouped content sections where different types of blocks are grouped together or contained within a parent block.
In this guide, you’ll learn how to:
- Create a block that contains other blocks.
- Use the InnerBlocks component to manage nested blocks.
- Customize and lock block templates to maintain structure.
What are Nested Blocks in Gutenberg?
Nested blocks allow you to create more complex layouts by embedding multiple blocks within a parent block. The most common examples of nested blocks are the Group block or the Columns block, where multiple child blocks are grouped or arranged in a grid.
Using InnerBlocks, you can create a parent block that allows users to add other blocks inside it, giving them the freedom to structure their content in a more flexible and organized way.
Step 1: Creating a Parent Block with InnerBlocks
Let’s start by creating a Container Block that allows users to add any type of block inside it.
- Register the Parent Block
In your block registration file (e.g., blocks/container-block.js
), define the block and use the InnerBlocks
component to handle nested blocks.
import { registerBlockType } from '@wordpress/blocks';
import { InnerBlocks } from '@wordpress/block-editor';
registerBlockType('my-theme/container-block', {
title: 'Container Block',
icon: 'screenoptions',
category: 'my-custom-category',
edit: () => {
return (
<div className="container-block">
<InnerBlocks />
</div>
);
},
save: () => {
return (
<div className="container-block">
<InnerBlocks.Content />
</div>
);
},
});
Explanation:
- InnerBlocks: This component allows other blocks to be nested inside the parent block. The
InnerBlocks
component in theedit
function lets users add blocks within the Container Block in the editor, whileInnerBlocks.Content
ensures those blocks are saved and displayed on the front end.
Step 2: Using Templates with InnerBlocks
To guide users when creating content within the Container Block, you can define block templates. Templates predefine the structure by specifying which child blocks should be included and how they should be arranged.
- Add a Block Template
Let’s update the Container Block to include a template that starts with two Paragraph blocks by default.
registerBlockType('my-theme/container-block', {
title: 'Container Block',
icon: 'screenoptions',
category: 'my-custom-category',
edit: () => {
const template = [
['core/paragraph', { placeholder: 'Enter text...' }],
['core/paragraph', { placeholder: 'Add another paragraph...' }],
];
return (
<div className="container-block">
<InnerBlocks template={template} />
</div>
);
},
save: () => {
return (
<div className="container-block">
<InnerBlocks.Content />
</div>
);
},
});
Explanation:
- Template: The
template
prop defines an array of blocks that are pre-inserted when the user adds the Container Block. In this case, two Paragraph blocks are included by default, each with its own placeholder text.
Step 3: Locking the Template Structure
In some cases, you might want to lock the block template so that users can’t add or remove blocks, only edit the content within the predefined structure. This is helpful for maintaining consistent layouts.
- Lock the Block Template
Update the InnerBlocks
component to lock the template structure.
registerBlockType('my-theme/container-block', {
title: 'Container Block',
icon: 'screenoptions',
category: 'my-custom-category',
edit: () => {
const template = [
['core/paragraph', { placeholder: 'Enter text...' }],
['core/paragraph', { placeholder: 'Add another paragraph...' }],
];
return (
<div className="container-block">
<InnerBlocks template={template} templateLock="all" />
</div>
);
},
save: () => {
return (
<div className="container-block">
<InnerBlocks.Content />
</div>
);
},
});
Explanation:
- templateLock=”all”: This locks the block template, preventing users from adding, removing, or moving blocks inside the Container Block. They can only edit the content of the pre-defined blocks.
Step 4: Customizing Nested Block Options
You can also restrict which types of blocks are allowed inside the parent block by using the allowedBlocks
prop.
- Restrict the Allowed Blocks
Let’s update the Container Block to only allow Heading and Paragraph blocks inside it.
registerBlockType('my-theme/container-block', {
title: 'Container Block',
icon: 'screenoptions',
category: 'my-custom-category',
edit: () => {
const allowedBlocks = ['core/paragraph', 'core/heading'];
return (
<div className="container-block">
<InnerBlocks allowedBlocks={allowedBlocks} />
</div>
);
},
save: () => {
return (
<div className="container-block">
<InnerBlocks.Content />
</div>
);
},
});
Explanation:
- allowedBlocks: This restricts the blocks that users can add to the Container Block. In this case, only Paragraph and Heading blocks are allowed.
Step 5: Testing Nested Blocks
- Rebuild the Block:
- Run your build command to ensure the block and its nested structure are properly loaded.
npm run build
- Test in the Block Editor:
- Add the Container Block to a post or page and test the nested block functionality. If you’ve defined a template or locked the structure, verify that users can only interact with the predefined blocks.
- Check the Front-End Display:
- Preview the post or page on the front end to ensure that the nested blocks render correctly.
Best Practices for Nested Blocks
- Use Templates Wisely: Define block templates that provide a useful starting point for users, while still allowing flexibility in how the content is structured.
- Lock Structure When Necessary: Lock the template when you need to maintain a strict layout, such as in reusable or predefined content sections.
- Restrict Block Types: Limit the types of blocks that can be nested inside your parent block to ensure consistency and avoid unexpected content formats.
Conclusion: Creating Complex Layouts with Nested Blocks
Nested blocks are a powerful tool in Gutenberg for creating complex, structured content layouts. By using InnerBlocks, you can allow users to add multiple child blocks inside a parent block, customize templates, and control how content is structured. Whether you’re building columns, grids, or grouped content, nested blocks provide the flexibility needed to handle more advanced content scenarios.
In this article, you’ve learned how to:
- Create a parent block that contains other blocks.
- Use InnerBlocks to manage nested content.
- Define templates and lock block structures for more control.
In Day 22, we’ll explore reusable blocks in Gutenberg, where users can save blocks for reuse across multiple posts or pages.
Leave a Reply