skip to Main Content

Issue

I have a setup using Gutenberg blocks via ACF. One of these blocks is a Group block which has the following context:

"providesContext": {
    "acf/groupData": "data"
}

I am then using <InnerBlocks /> inside the group block template file.

Each of the blocks that can be nested in this group block have a value of:

"usesContext": ["acf/groupData"]

This works perfect and the group values are passed into the $context array for use within the inner blocks.

However, if I add a Synced Pattern block inside this group block, the context is lost and acf/groupData is not part of the $context array.

Hoping someone can help, would be great if there’s a way to pass down the group context into synced patterns.

Tried

I’ve had a look around to see if there’s any hooks relating to when patterns are created to see if I can pass the context through there but no luck.

I also tried creating a function that would grab the post content, parse the blocks and try and get the group block from there, however, the block ID’s aren’t returned when using the post content, only the block name and attributes etc.

2

Answers


  1. Unfortunately, Synced Patterns (previously known as "Reusable Blocks") do not inherit context by design, because of how they are intended to be used across posts/pages and templates so they do not rely on context being provided.

    Reviewing your scenario, the Group block provides context of "acf/groupData" to InnerBlocks in the Editor, which works, although block context cannot be saved. Each of your nested blocks within InnerBlocks consume "acf/groupData" and if they are rendered dynamically, they can use the provided context on the frontend, eg:

    render.php

    <?php
    /**
     * @see https://github.com/WordPress/gutenberg/blob/trunk/docs/reference-guides/block-api/block-metadata.md#render
     * $attributes (array): The block attributes.
     * $content (string): The block default content.
     * $block (WP_Block): The block instance.
     * 
     * Example render callback for child/nested block contained within InnerBlocks
     * that receives context from Parent
     */
    ?>
    
    <div <?php echo get_block_wrapper_attributes(); ?>>
        <?php echo $block->context['acf/groupData']; // prints "data" ?>
    </div>
    

    If you then saved this as a Synced Pattern, a warning Undefined array key “acf/groupData” is triggered as the parent blocks’ context does not exist to the Synced Pattern because Synced Patterns are actually saved as a custom post type (wp_block) in the database to be reused/included in other content.

    Possible Workaround

    Instead of Synced Patterns, I would:

    • Define a Template for InnerBlocks in the Group block that lists the nested/child blocks required (and any default values for each).
    • Register Block Variations (if required) of the Group block that varies the InnerBlocks Template which removes the need for Synced Patterns while maintaining the context between Parent – Child.
    • Use Dynamic Blocks for the nested/child blocks to enable it "acf/groupData" to be rendered on the frontend (see render.php example above).
    Login or Signup to reply.
  2. The context loss with Synced Patterns is a known limitation because patterns are treated as separate entities. Here are two potential solutions:

    1. Pass context via pattern attributes:
    register_block_pattern(
        'namespace/pattern-name',
        [
            'title' => 'Pattern Title',
            'attributes' => [
                'groupData' => [
                    'type' => 'object',
                    'default' => null
                ]
            ]
        ]
    );
    

    Then modify your group block to pass data as attributes:

    $block_content = str_replace(
        '<InnerBlocks',
        '<InnerBlocks groupData="' . esc_attr(wp_json_encode($context['data'])) . '"',
        $block_content
    );
    
    1. Use WordPress’s block context filter:
    add_filter('render_block_context', function($context, $parsed_block) {
        if ($parsed_block['blockName'] === 'core/pattern') {
            $parent_context = wp_get_block_context();
            if (isset($parent_context['acf/groupData'])) {
                $context['acf/groupData'] = $parent_context['acf/groupData'];
            }
        }
        return $context;
    }, 10, 2);
    

    The first approach is more reliable but requires pattern modification. The second is global but may have edge cases.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search