Make WordPress Core

Opened 7 months ago

Last modified 7 weeks ago

#63580 new defect (bug)

render_block does not render innerblocks when used explicitly

Reported by: yashjawale's profile yashjawale Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version:
Component: Editor Keywords: 2nd-opinion
Focuses: Cc:

Description

When using render_blocks explicitly, it doesn't render the nested blocks if they don't have any innerContent defined in them.

I believe this shouldn't be the case as some parent blocks like core/column shouldn't won't necessarily have innerContent when other blocks are present inside them.

For example, this doesn't render the content of the nested paragraph blocks

<?php
$first_column_blocks = [
        [
                'blockName' => 'core/paragraph',
                'attrs' => [],
                'innerBlocks' => [],
                'innerHTML' => '<p>This is the first column demo content.</p>',
                'innerContent' => [
                        '<p>This is the first column demo content.</p>',
                ],
        ],
];

$second_column_blocks = [
        [
                'blockName' => 'core/paragraph',
                'attrs' => [],
                'innerBlocks' => [],
                'innerHTML' => '<p>This is the second column demo content.</p>',
                'innerContent' => [
                        '<p>This is the second column demo content.</p>',
                ],
        ],
];

$column_layout_block = [
        'blockName' => 'core/columns',
        'attrs' => [],
        'innerBlocks' => [
                [
                        'blockName' => 'core/column',
                        'attrs' => [],
                        'innerBlocks' => $first_column_blocks
                ],
                [
                        'blockName' => 'core/column',
                        'attrs' => [],
                        'innerBlocks' => $second_column_blocks
                ],
        ]
];

For markup generated by Gutenberg, there is some innerContent generated hence, it doesn't the same issue. But I don't think a developer is expected to pass this content in explicitly [demonstrated in linked image]

More info present in Gutenberg ticket linked below


This issue was originally reported by Andreas Lindahl as an Issue on Gutenberg repository
https://github.com/WordPress/gutenberg/issues/69307

Attachments (3)

451341949-e21093e1-ffc1-4626-90dd-cf783b633644.png (76.4 KB) - added by yashjawale 7 months ago.
innerContent generated by same layout created in Gutenberg editor instead
innercontent-absent.png (89.4 KB) - added by lakshyajeet 6 months ago.
When innerContent is not defined then nothing gets rendered
innercontent-present.png (93.4 KB) - added by lakshyajeet 6 months ago.
When innerContent is added the block is rendered properly from the content.

Download all attachments as: .zip

Change History (9)

@yashjawale
7 months ago

innerContent generated by same layout created in Gutenberg editor instead

#1 @yashjawale
7 months ago

I've narrowed down the cause to innerContent check in render() method of class-wp-block.php

I'll be happy to work on a patch for this issue if this isn't expected behavior

Ref: https://github.com/yashjawale/wordpress-develop/blob/fc41a79118c10a897e0b29b97d40bea110cebafc/src/wp-includes/class-wp-block.php#L534

This ticket was mentioned in Slack in #core by yash_jawale. View the logs.


7 months ago

#3 @yashjawale
7 months ago

  • Focuses template removed
  • Keywords 2nd-opinion added

#4 @lakshyajeet
6 months ago

Reproduction Report

Description

This report validates whether the issue can be reproduced.

Environment

  • WordPress: 6.9-alpha-60093-src
  • PHP: 8.2.29
  • Server: nginx/1.29.0
  • Database: mysqli (Server: 8.4.5 / Client: mysqlnd 8.2.29)
  • Browser: Chrome 137.0.0.0
  • OS: macOS
  • Theme: Twenty Twenty-Five 1.3
  • MU Plugins: None activated
  • Plugins:
    • Test Reports 1.2.0

Actual Results

  1. ✅ Error condition occurs, the bug can be reproduced.

Additional Notes

When programmatically defining WordPress block structures and rendering them using render_block(), inner blocks (nested blocks) are not rendered if their direct parent block (or any ancestor in the block tree) is missing the innerContent array in its block definition.

Specifically, if a block array has innerBlocks populated but lacks an innerContent array (or if the innerContent array does not contain the correct integer indices corresponding to its innerBlocks), the children blocks will not appear in the final rendered output.

This behavior was observed with core/group, and core/column blocks.

Supplemental Artifacts

Code that reproduces the issue (blocks not rendered):

<?php

$first_column_blocks = [
        'blockName' => 'core/paragraph',
        'attrs' => [],
        'innerBlocks' => [],
        'innerHTML' => '<p>First Global HTML</p>',
        'innerContent' => [
                '<p>First Global HTML</p>',
        ],
];

$second_column_blocks = [
        'blockName' => 'core/paragraph',
        'attrs' => [],
        'innerBlocks' => [],
        'innerHTML' => '<p>Second Global HTML</p>',
        'innerContent' => [
                '<p>Second Global HTML</p>',
        ],
];

$column_layout_block = [
        'blockName' => 'core/columns',
        'attrs' => [],
        'innerBlocks' => [
                [
                        'blockName' => 'core/group',
                        'attrs' => [],
                        'innerBlocks' => [$first_column_blocks],
                ],
                [
                        'blockName' => 'core/group',
                        'attrs' => [],
                        'innerBlocks' => [$second_column_blocks],
                ],
        ],
];

add_action('template_redirect', function() {
        global $column_layout_block;
        echo apply_filters('the_content', render_block($column_layout_block));
        // Expected: Group Block gets rendered
        // Actual Result: Nothing is rendered 
});

?>

Code that works correctly (blocks are rendered):

<?php

$first_column_blocks = [
        'blockName' => 'core/paragraph',
        'attrs' => [],
        'innerBlocks' => [],
        'innerHTML' => '<p>First Global HTML</p>',
        'innerContent' => [
                '<p>First Global HTML</p>',
        ],
];

$second_column_blocks = [
        'blockName' => 'core/paragraph',
        'attrs' => [],
        'innerBlocks' => [],
        'innerHTML' => '<p>Second Global HTML</p>',
        'innerContent' => [
                '<p>Second Global HTML</p>',
        ],
];

$column_layout_block = [
        'blockName' => 'core/columns',
        'attrs' => [],
        'innerBlocks' => [
                [
                        'blockName' => 'core/group',
                        'attrs' => [],
                        'innerBlocks' => [$first_column_blocks],
                        'innerContent' => [
                                '<p>First Group Inner</p>',
                        ],
                ],
                [
                        'blockName' => 'core/group',
                        'attrs' => [],
                        'innerBlocks' => [$second_column_blocks],
                        'innerContent' => [
                                '<p>Second Group Inner</p>',
                        ],
                ],
        ],
        'innerContent' => [
                '<p>First Group Content</p>',
                '<p>Second Group Content</p>'
        ]
];

add_action('template_redirect', function() {
        global $column_layout_block;
        echo apply_filters('the_content', render_block($column_layout_block));
        // Result: Blocks are rendered when innerContent is provided.

        // First Group Content
        // Second Group Content
});

?>
Last edited 6 months ago by lakshyajeet (previous) (diff)

@lakshyajeet
6 months ago

When innerContent is not defined then nothing gets rendered

@lakshyajeet
6 months ago

When innerContent is added the block is rendered properly from the content.

#5 @iamadisingh
6 months ago

Reproduction Report

Description

This report validates whether the issue can be reproduced.

Environment

  • WordPress: 6.9-alpha-60093-src
  • PHP: 8.2.28
  • Server: nginx/1.27.3
  • Database: mysqli (Server: 8.4.5 / Client: mysqlnd 8.2.28)
  • Browser: Chrome 138.0.0.0
  • OS: macOS
  • Theme: Twenty Twenty-Five 1.2
  • MU Plugins: None activated
  • Plugins:
    • Test Render Block Issue 1.0.0
    • Test Reports 1.2.0

Actual Results

  1. ✅ Error condition occurs (reproduced).

Additional Notes

  • When using render_block() explicitly with programmatically created block structures, nested blocks (innerBlocks) are not rendered if the parent block lacks an innerContent array. This affects container blocks like core/column and core/columns where the parent block should render its child blocks even without explicit innerContent markup.
  • Parent blocks with innerBlocks should render their child blocks regardless of whether innerContent is defined, as the child blocks contain valid innerHTML and innerContent properties.
  • The issue lies in how WordPress's WP_Block::render() method processes blocks. The fix should be in the WP_Block::render() method to ensure that innerBlocks are processed even when innerContent is empty, while maintaining backward compatibility with existing behavior.

Supplemental Artifacts

Plugin code used for reproducing the error

<?php
/**
 * Plugin Name: Test Render Block Issue
 * Description: A plugin to test rendering of blocks with inner blocks.
 * Version: 1.0.0
 */

$first_column_blocks = [
    'blockName' => 'core/paragraph',
    'attrs' => [],
    'innerBlocks' => [],
    'innerHTML' => '<p>First Global HTML</p>',
    'innerContent' => [
            '<p>First Global HTML</p>',
    ],
];

$second_column_blocks = [
    'blockName' => 'core/paragraph',
    'attrs' => [],
    'innerBlocks' => [],
    'innerHTML' => '<p>Second Global HTML</p>',
    'innerContent' => [
            '<p>Second Global HTML</p>',
    ],
];

$column_layout_block = [
    'blockName' => 'core/columns',
    'attrs' => [],
    'innerBlocks' => [
            [
                    'blockName' => 'core/group',
                    'attrs' => [],
                    'innerBlocks' => [$first_column_blocks],
                    'innerContent' => [
                            null,
                    ],
            ],
            [
                    'blockName' => 'core/group',
                    'attrs' => [],
                    'innerBlocks' => [$second_column_blocks],
                    'innerContent' => [
                            null,
                    ],
            ],
    ],
    'innerContent' => [ null, null] // Required without this nested blocks won't render
];

add_action('template_redirect', function() {
    global $column_layout_block;
    echo apply_filters('the_content', render_block($column_layout_block));
});

When innerContent is added - https://files.catbox.moe/j1qdyr.png
Without innerContent in parent block - https://files.catbox.moe/mitk2k.png

Last edited 6 months ago by iamadisingh (previous) (diff)

#6 @wildworks
7 weeks ago

  • Version trunk deleted

I'm checking this ticket in preparation for the 6.9 dry run.

Code that reproduces the issue (blocks not rendered):

I tested this issue with WordPress 6.8.3 and was able to reproduce the problem, so it's not an issue occurring in an unreleased development version.

Note: See TracTickets for help on using tickets.