Make WordPress Core

Opened 20 hours ago

Last modified 20 hours ago

#66415 new enhancement

Block Bindings: Add innerBlock bindings compatibility.

Reported by: cbravobernal Owned by:
Priority: normal Milestone:
Component: General Version:
Severity: normal Keywords: has-patch has-unit-tests
Cc: Focuses:

Description

Block bindings can currently only replace block attributes. This ticket proposes letting a block bindings source supply the inner blocks of a Group or Column block, through a new innerBlocks binding:

<!-- wp:group {"metadata":{"bindings":{"innerBlocks":{"source":"my-plugin/stats","args":{"key":"completed"}}}}} -->
<div class="wp-block-group"></div>
<!-- /wp:group -->

The source returns serialized block markup. The supplied blocks replace the block's own inner blocks before they render, with the block's context. An empty string leaves the block empty. Any other value, such as plain text, keeps the block's own inner blocks.

How it works:

  • WP_Block::process_block_bindings() handles innerBlocks itself instead of treating it as an attribute.
  • The markup is sanitized with wp_kses_post(), as bound rich text already is, and custom CSS is removed from the supplied blocks.
  • Supplied blocks can't bind their own inner blocks, so two sources can't expand each other forever.
  • The blocks go where the block's own inner blocks were. A block without any gets them before the closing tag of its wrapper, found with the HTML API.
  • The editor isn't offered innerBlocks yet, as it doesn't render these bindings.

Gutenberg PR: ​https://github.com/WordPress/gutenberg/pull/85568

Change History (1)

This ticket was mentioned in ​PR #15164 on ​WordPress/wordpress-develop by ​@cbravobernal.


20 hours ago
#1

  • Keywords has-patch has-unit-tests added

What?

Lets a block bindings source supply the inner blocks of a Group or Column block through metadata.bindings.innerBlocks. Backports the server part of WordPress/gutenberg#85568.

How?

  • WP_Block::process_block_bindings() handles innerBlocks itself and calls a new private replace_inner_blocks(), instead of treating it as an attribute.
  • The value is serialized block markup. It's sanitized with wp_kses_post(), as bound rich text already is, and the supplied blocks lose their custom CSS and their own innerBlocks bindings, so sources can't expand each other forever.
  • The blocks go where the block's own inner blocks were. A block without any gets them before the closer of its wrapper, found with WP_HTML_Processor.
  • __default pattern overrides bindings never expand to innerBlocks.
  • get_block_editor_settings() leaves innerBlocks out, as the editor doesn't render these bindings yet.

Testing

npm run test:php -- --group block-bindings: the new tests/phpunit/tests/block-bindings/innerBlocks.php covers the value contract, sanitizing, recursion, placement and the editor settings.

Replaces #12432, which backported an earlier design.

🤖 Generated with ​Claude Code

Note: See TracTickets for help on using tickets.