Day 28: Building Dynamic Block Templates in Gutenberg

Introduction

Welcome to Day 28 of the Gutenberg development series! Today, we’ll dive into dynamic block templates, which allow you to create layouts that adapt based on user input or specific conditions. Dynamic templates make it possible to create interactive content structures, such as user-specific welcome messages, conditionally displayed call-to-action blocks, and more.

In this guide, you’ll learn how to:

  • Define dynamic templates for blocks.
  • Use conditional logic to adjust block content.
  • Create templates that adjust based on user roles or metadata.

What are Dynamic Block Templates in Gutenberg?

Dynamic block templates are predefined layouts that can adjust based on user input or other conditions. Unlike static templates, which remain the same for every instance, dynamic templates can change their structure or content based on specific criteria. This is useful for:

  • Personalized Content: Show different content based on user roles or preferences.
  • Interactive Layouts: Adjust the structure of a page based on selections or user input.
  • Advanced Customization: Create templates that adapt to various scenarios, like showing different blocks based on whether a user is logged in or not.

Step 1: Creating a Dynamic Template with Conditional Blocks

Let’s create a Welcome Block that displays different content based on whether a user is logged in or not.

  1. Register the Welcome Block

In your block registration file (e.g., blocks/welcome-block.js), define the block and use conditional rendering to adjust the displayed content.

import { registerBlockType } from '@wordpress/blocks';
import { useSelect } from '@wordpress/data';

registerBlockType('my-theme/welcome-block', {
    title: 'Welcome Block',
    icon: 'smiley',
    category: 'my-theme-blocks',
    edit: () => {
        const isLoggedIn = useSelect((select) => select('core').isUserLoggedIn(), []);
        const welcomeMessage = isLoggedIn ? 'Welcome back, valued user!' : 'Hello, please log in to access more features.';

        return (
            <div className="welcome-block">
                <p>{welcomeMessage}</p>
            </div>
        );
    },
    save: () => null, // Server-side rendered block
});

Explanation:

  • useSelect: This hook allows you to access the WordPress data store and determine if a user is logged in.
  • Conditional Message: Displays a different welcome message depending on the user’s login status.
  • Server-Side Rendered: The block is saved with save: () => null, which means it will be rendered on the server, allowing the content to adapt dynamically on the front end.

Step 2: Adding Conditional Logic for User Roles

You can further customize the block to display different messages based on the user’s role (e.g., Administrator, Subscriber).

  1. Enhance the Welcome Block with Role-Based Messages

Update the edit function to include role-based logic:

import { select } from '@wordpress/data';

const getUserRole = () => {
    const user = select('core').getCurrentUser();
    return user?.roles?.[0] || 'guest';
};

registerBlockType('my-theme/welcome-block', {
    title: 'Welcome Block',
    icon: 'smiley',
    category: 'my-theme-blocks',
    edit: () => {
        const role = getUserRole();
        let welcomeMessage;

        switch (role) {
            case 'administrator':
                welcomeMessage = 'Welcome back, Admin! Here are your latest updates.';
                break;
            case 'subscriber':
                welcomeMessage = 'Hello, valued subscriber! Enjoy your personalized content.';
                break;
            default:
                welcomeMessage = 'Welcome! Please log in or register to access more features.';
        }

        return (
            <div className="welcome-block">
                <p>{welcomeMessage}</p>
            </div>
        );
    },
    save: () => null, // Server-side rendered block
});

Explanation:

  • getUserRole: Retrieves the current user’s role from the WordPress store.
  • Switch Statement: Uses a switch statement to adjust the message based on the user’s role, providing personalized content for different user types.

Step 3: Using Dynamic Templates with Metadata

You can also create dynamic templates that adjust based on post metadata or custom fields.

  1. Register a Dynamic Template for a Custom Post Type

Let’s create a Project Block that displays different information based on custom metadata (e.g., Project Status).

registerBlockType('my-theme/project-block', {
    title: 'Project Block',
    icon: 'portfolio',
    category: 'my-theme-blocks',
    edit: ({ attributes, setAttributes }) => {
        const { projectStatus } = attributes;

        const statusMessage = projectStatus === 'completed'
            ? 'This project is completed. Check out the final results below.'
            : 'This project is in progress. Stay tuned for updates.';

        return (
            <div className="project-block">
                <select
                    value={projectStatus}
                    onChange={(event) => setAttributes({ projectStatus: event.target.value })}
                >
                    <option value="in-progress">In Progress</option>
                    <option value="completed">Completed</option>
                </select>
                <p>{statusMessage}</p>
            </div>
        );
    },
    attributes: {
        projectStatus: {
            type: 'string',
            default: 'in-progress',
        },
    },
    save: ({ attributes }) => {
        const { projectStatus } = attributes;
        return (
            <div className={`project-block ${projectStatus}`}>
                <p>
                    {projectStatus === 'completed'
                        ? 'This project is completed. Check out the final results below.'
                        : 'This project is in progress. Stay tuned for updates.'}
                </p>
            </div>
        );
    },
});

Explanation:

  • Custom Metadata: Uses a dropdown to set the projectStatus attribute, allowing users to change the message displayed.
  • Dynamic Output: Adjusts the content based on the value of projectStatus, making it easy to change messages as the project progresses.

Step 4: Testing Dynamic Block Templates

  1. Rebuild the Blocks:
    • Run your build command to ensure the updated dynamic blocks are properly loaded.
npm run build
  1. Test in the Editor:
    • Add the Welcome Block or Project Block to a post or page.
    • Adjust the settings (like project status) or log in with different user roles to see how the content adapts.
  2. Check the Front-End Display:
    • Preview the post or page on the front end to ensure that the dynamic adjustments are functioning as expected.

Best Practices for Dynamic Block Templates

  1. Use Dynamic Templates for Personalization: Leverage user roles, metadata, and other criteria to deliver tailored content to different user groups.
  2. Test Across User Scenarios: Ensure that your dynamic templates function correctly for different user roles and metadata states.
  3. Keep Logic Manageable: Avoid overly complex logic within your block’s edit function. Use helper functions to keep the code clean and maintainable.

Conclusion: Building Interactive Experiences with Dynamic Templates

Dynamic block templates allow you to create highly customized content experiences in Gutenberg. Whether you’re tailoring messages based on user roles, adjusting content based on metadata, or creating interactive layouts, dynamic templates enable you to deliver more engaging and relevant content.

In this article, you’ve learned how to:

  • Create dynamic templates that adjust based on user roles.
  • Use custom metadata to change block content.
  • Implement dynamic behavior with the WordPress data store.

In Day 29, we’ll explore optimizing block performance to ensure that custom blocks load quickly and efficiently in the Block Editor and on the front end.


Leave a Reply

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