PHP-only blocks: Add pattern support - #79598
Conversation
|
👋 Thanks for your first Pull Request and for helping build the future of Gutenberg and WordPress, @priethor! In case you missed it, we'd love to have you join us in our Slack community. If you want to learn more about WordPress development in general, check out the Core Handbook full of helpful information. |
8382328 to
8a37787
Compare
|
Size Change: +308 B (0%) Total Size: 7.61 MB 📦 View Changed
|
|
Flaky tests detected in 3dd7f61. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/28460170562
|
|
Worth flagging a trade-off in this initial exploration, because it’ll probably come up in review: in the canvas-editable modes, the You can see it in the example: the editor shows a bare heading and paragraph, but the frontend wraps them in the pattern-block-demo container with the “Featured” ribbon and variant classes. None of that PHP decoration shows up while you’re editing. The way it's currently implemented, there's a trilemma of things the block developer would want, and right now, they can only get two at once:
No I think there's another way worth trying: render the PHP shell server-side in the editor as well, with the editable blocks as islands within it. That’s basically |
8a37787 to
1f21ed2
Compare
1f21ed2 to
61491ff
Compare
|
Instead of polluting this first iteration, I tried to leverage the new |
|
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 If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
The more I look at it, the more it looks like the best solution. Moreover, I don’t think content-only mode is the right fit here, so I’d drop it. The way I see it, there’s really just one "mode" that matters: when the block has a Without a |
|
Closed in favor of #79831 |
What
Part of #79330.
Adds experimental support for PHP-only auto-registered blocks that provide a
pattern. When the experiment is enabled, the editor uses that pattern as real, editable block content instead of treating the block only as a ServerSideRender preview.Why
In 7.0, a PHP-only block is a server-rendered preview in the editor, and its content can only be edited through the Inspector, never in the canvas.
This PR lets that content be edited directly in the canvas, while PHP can still process the edited content at render time to wrap or transform the output. The block keeps server-side rendering but stops being a black box in the editor.
A content-only pattern already gives editable canvas content, so that part is not new. What a pattern cannot give is a registered block: a
render_callbackthat runs over the edited content, and a name and namespace that CSS, block styles,theme.json, and filters can target. If a block only needs editable markup with no server processing, a content-only pattern is enough and this is not needed.How
A PHP-only block provides a
pattern. The editor renders it as editable inner blocks and saves the user's edits as those inner blocks; on the frontend, the optionalrender_callbackreceives them as$content.Under the hood:
Examples
The PR adds a shared pattern to the server-side rendered block test plugin:
The
render_callbackis optional for the canvas-editable blocks: without it, the saved inner blocks render natively on the frontend. The examples include it to show the combination. It receives the edited content as$content, wraps it, and adds a "Featured" ribbon and variant classes from the attributes, falling back to the pattern when there is no saved content:The default option is a canvas-editable pattern using
contentOnlylocking. This keeps the structure tight, but the content-only UI hides the generated Inspector controls (see the second block in the video below):A block can keep the normal Inspector visible by setting
patternLocktofalse. The trade-off is a softer structural lock (third block in the video below):A block can also opt out of canvas editing and keep a server-rendered editor preview (first block in the video). That path is useful when the controls need to update the preview live, but it means the pattern content is not editable directly in the canvas:
In the two canvas-editable examples, the render callback receives the saved inner block markup as
$contenton the frontend. The SSR example falls back to rendering the shared pattern when there is no saved inner content.Testing Instructions
Screen recording
Grabacion.de.pantalla.2026-06-26.a.las.20.37.40.mov
I used Claude and GPT to implement the code changes while I guided and reviewed the approach.