Skip to content

Block Bindings: Add list item content support#78991

Draft
cbravobernal wants to merge 2 commits into
WordPress:trunkfrom
cbravobernal:add/list-item-block-bindings-v2
Draft

Block Bindings: Add list item content support#78991
cbravobernal wants to merge 2 commits into
WordPress:trunkfrom
cbravobernal:add/list-item-block-bindings-v2

Conversation

@cbravobernal
Copy link
Copy Markdown
Contributor

@cbravobernal cbravobernal commented Jun 6, 2026

What?

Adds Block Bindings support for the core/list-item block's content attribute.

Supersedes #78947 by preserving its list-item supported-attribute commit and adding the nested-list-safe render path.

Core backport: WordPress/wordpress-develop#12113.

Why?

List Item stores its rich-text content and nested List inner blocks inside the same <li>. The generic rich-text binding replacement path can replace the whole <li> contents, which drops nested lists. Supporting this block in the Gutenberg plugin needs to update only the list item's leading rich-text content while preserving nested inner blocks.

The compatibility workaround is deliberate: the current block bindings path does not expose a clean seam to resolve a bound value without also replacing the markup. To stay contained, this PR hides list-item content bindings from the generic replacement path, resolves them through the existing resolver later, and applies a list-item-specific replacement.

How?

  • Adds content to the server-provided supported attributes for core/list-item in the WordPress 7.1 compat layer.
  • Stashes list-item content bindings during render_block_data so the generic replacement path does not process them first.
  • Resolves the bound value through the existing gutenberg_process_block_bindings() helper, then replaces only the list item rich text with a nested-list-aware HTML processor.
  • Uses block structure to distinguish delimiter-backed nested inner blocks from raw markup that should be replaced.
  • Preserves nested unordered, ordered, and deeper list inner blocks, sanitizes bound HTML with the same wp_kses_post() path, and keeps pattern override __default metadata expansion consistent with the generic path.
  • Adds the Core backport changelog entry for Block Bindings: Preserve nested inner blocks when binding rich text wordpress-develop#12113.
  • Updates the Block Bindings supported attributes docs table.

Future direction

WordPress/wordpress-develop#12113 implements the cleaner Core-side version by recording inner-block render offsets inside WP_Block::render() and letting rich-text replacement stop at the first inner block. This Gutenberg PR keeps a narrower compat bridge because the plugin cannot change the host Core WP_Block::render() implementation on older WordPress installs.

Testing Instructions

  1. Run npm run test:unit:php:base -- --filter Tests_Block_Bindings.
  2. Run PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 npm run test:e2e -- test/e2e/specs/editor/various/block-bindings/custom-sources.spec.js --grep "list item".
  3. Optional manual check: create a list item with metadata.bindings.content, include a nested List block under it, and confirm the front end renders the bound list item content while keeping the nested list.

Testing Instructions for Keyboard

No new keyboard interactions are introduced. Existing List Item editing, indentation, and rich-text keyboard behavior are unchanged.

Screenshots or screencast

Not applicable; this is render and binding compatibility behavior covered by tests.

Use of AI Tools

Claude was used to help author the implementation/tests in the branch commit and Core backport direction, and Codex was used for review passes, metadata cleanup, documentation/backport-changelog updates, and validation. The changes were reviewed before requesting review.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 6, 2026

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Unlinked Accounts

The following contributors have not linked their GitHub and WordPress.org accounts: @[email protected].

Contributors, please read how to link your accounts to ensure your work is properly credited in WordPress releases.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Unlinked contributors: [email protected].

Co-authored-by: cbravobernal <[email protected]>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

Add server-side rendering support so a bound `core/list-item` content
attribute is replaced without dropping nested List inner blocks rendered
inside the same `<li>`.

All logic lives in the wordpress-7.1 compat layer: a `render_block_data`
filter hides the binding from Core's generic rich-text replacement, and a
`render_block` filter resolves the value through the existing
`gutenberg_process_block_bindings()` helper and applies it with a
nested-list-aware replacement. The shipped wordpress-6.9 block-bindings
code is left untouched and no new hooks are introduced.

Adds PHPUnit coverage (plain text, nested/ordered/deep lists, empty value,
pattern overrides, sanitization, non-list inner blocks) and an editor e2e
test.

Builds on WordPress#78947 (list-item block bindings support).

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
@cbravobernal cbravobernal force-pushed the add/list-item-block-bindings-v2 branch from 6bcecfa to dab2d81 Compare June 7, 2026 09:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Type] Enhancement A suggestion for improvement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant