Day 18: Creating Custom Block Transforms in Gutenberg

Introduction

Welcome to Day 18 of the Gutenberg development series! In today’s article, we’ll explore custom block transforms, which enable users to convert one block type into another without losing content. This feature is especially useful when users want to change a block’s layout or functionality but retain the core content, like converting a paragraph into a heading or changing a list block into individual paragraphs.

In this guide, you’ll learn how to:

  • Define block transforms to convert between different block types.
  • Customize block transformation behavior to provide more options to users.
  • Ensure smooth content transitions during block conversion.

What are Block Transforms?

Block transforms in Gutenberg allow users to switch between block types while preserving the content inside the block. For example, a user might want to convert a paragraph block into a heading block, or turn a list block into individual paragraph blocks. This improves the editing experience by allowing users to adapt the layout or functionality of blocks without re-entering content.

Block transforms are available for core blocks in WordPress, and you can define custom transforms for your own custom blocks.

Step 1: Defining a Simple Block Transform

Let’s start by defining a simple block transform that converts a paragraph block into a heading block. This is a common use case when users want to upgrade their text content to a more prominent heading.

  1. Register a Block Transform

In your block registration file (e.g., blocks/paragraph-to-heading.js), use the addTransform function to define the transformation.

import { registerBlockType } from '@wordpress/blocks';
import { createBlock } from '@wordpress/blocks';

// Register a Paragraph block
registerBlockType('my-theme/paragraph-block', {
    title: 'Paragraph Block',
    icon: 'editor-paragraph',
    category: 'text',
    attributes: {
        content: {
            type: 'string',
        },
    },
    edit: ({ attributes, setAttributes }) => {
        const { content } = attributes;
        return (
            <textarea
                value={content}
                onChange={(event) => setAttributes({ content: event.target.value })}
                placeholder="Write your paragraph..."
            />
        );
    },
    save: ({ attributes }) => {
        return <p>{attributes.content}</p>;
    },
});

// Define block transform from Paragraph to Heading
wp.blocks.addTransform('my-theme/paragraph-block', {
    transforms: {
        to: [
            {
                type: 'block',
                blocks: ['core/heading'],
                transform: ({ content }) => {
                    return createBlock('core/heading', {
                        content,
                    });
                },
                isMatch: ({ content }) => !!content,
                priority: 5,
            },
        ],
    },
});

Explanation:

  • addTransform: This function registers a transform for a block, defining how the block is converted.
  • transform: The actual function that handles the transformation. In this case, we’re transforming the paragraph’s content into a heading.
  • createBlock: This function creates a new block of a specific type (in this case, a heading) with the content carried over from the original block.

Step 2: Adding More Block Transforms

You can define multiple block transforms to give users more flexibility. Let’s add another transform that converts a paragraph block into a list block.

  1. Add Transform to Convert Paragraph to List

Update your transform code to include the ability to convert a paragraph into a list item.

wp.blocks.addTransform('my-theme/paragraph-block', {
    transforms: {
        to: [
            {
                type: 'block',
                blocks: ['core/heading'],
                transform: ({ content }) => {
                    return createBlock('core/heading', {
                        content,
                    });
                },
                isMatch: ({ content }) => !!content,
                priority: 5,
            },
            {
                type: 'block',
                blocks: ['core/list'],
                transform: ({ content }) => {
                    return createBlock('core/list', {
                        values: `<li>${content}</li>`,
                    });
                },
                isMatch: ({ content }) => !!content,
                priority: 10,
            },
        ],
    },
});

Explanation:

  • Transform to List: This adds a new block transformation that converts the paragraph’s content into a single list item.
  • values: "<li>": The content of the paragraph is wrapped in list item tags (<li>), which is how list blocks format their content.

Step 3: Handling Block Transforms in Reverse

Not only can you define transforms from one block to another, but you can also define reverse transforms. This is useful when users want to convert a block back to its original type or an alternative layout.

  1. Define a Reverse Transform

You can add a reverse transform to convert a heading block back into a paragraph.

wp.blocks.addTransform('core/heading', {
    transforms: {
        to: [
            {
                type: 'block',
                blocks: ['my-theme/paragraph-block'],
                transform: ({ content }) => {
                    return createBlock('my-theme/paragraph-block', {
                        content,
                    });
                },
                isMatch: ({ content }) => !!content,
                priority: 5,
            },
        ],
    },
});

Explanation:

  • Reverse Transform: This code allows users to convert a heading block back into a paragraph block by taking the heading’s content and applying it to the paragraph.

Step 4: Testing Block Transforms

After defining your block transforms, follow these steps to test them:

  1. Rebuild Your Block:
    • Run your build command to ensure the block and transforms are properly registered in the Block Editor.
npm run build
  1. Test in the Block Editor:
    • Add a Paragraph Block to a post or page.
    • Enter some text into the paragraph, then click on the block’s options.
    • Look for the “Transform to” option in the block toolbar, and try converting the paragraph into a heading or list.
    • Test the reverse transform by converting the heading back into a paragraph.
  2. Check the Content:
    • Ensure that the content inside the block is retained and transferred correctly during the block transformation.

Best Practices for Block Transforms

  1. Preserve Content: Ensure that all important content is preserved during the transformation. If a block contains multiple fields, be sure to map them appropriately to the new block type.
  2. Maintain Flexibility: Provide multiple transformation options where appropriate, giving users flexibility when switching between block types.
  3. Test Reversibility: If you’re offering reverse transforms (e.g., heading to paragraph and back), make sure the content remains intact after multiple transformations.

Conclusion: Enhancing User Flexibility with Block Transforms

Block transforms are an essential feature in Gutenberg, providing users with the flexibility to change block types without losing content. Whether converting a paragraph into a heading or turning text into a list, block transforms improve the overall editing experience by allowing easy transitions between content layouts.

In this article, you’ve learned how to:

  • Define block transforms to convert one block type into another.
  • Add multiple transforms to provide more options to users.
  • Handle reverse transforms to ensure smooth content transitions.

In Day 19, we’ll explore block deprecations, a feature that allows you to gracefully update blocks without breaking existing content.


Leave a Reply

Your email address will not be published. Required fields are marked *