티스토리 수익 글 보기
Navigation Menu
-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Pattern Overrides: Infer partial syncing supported blocks from the server #73889
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pattern Overrides: Infer partial syncing supported blocks from the server #73889
Conversation
This might be worth revisiting. I haven’t managed to create a pattern that includes a Navigation Link block (even with this PR applied) — I suspect that there are some checks for other criteria that prevent that (maybe it’s not possible to create patterns from the Site Editor?) At a practical level, if it’s impossible to create a pattern that includes a Nav Link block, the question of whether a Nav Link block’s attribute(s) should be overridable by pattern overrides becomes academic. To answer the question more generally, we should try to think of an example where a block should be supported by block bindings but not by pattern overrides. |
|
Size Change: +5 B (0%) Total Size: 3.08 MB
ℹ️ View Unchanged
|
|
Flaky tests detected in 518805a. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/20752179860
|
4f0c83e to
c7fb96a
Compare
|
@ockham I just spent a bit of time looking into this myself before realizing you already had this PR. I therefore didn’t create a new one but I have pushed my changes here: https://github.com/WordPress/gutenberg/compare/feature/filterable-pattern-overrides?expand=1 Maybe at least the docs changes could be useful 🙂 Let me know if there is any way in which I can support you here 👍 landing this would be a massive win 🙂 |
c7fb96a to
f037208
Compare
|
Hey @fabiankaegy! I’d be happy to land this soon. I think the main (perceived) blocker for me was that I was trying to figure out an example of a block attribute where that we’d want Block Bindings to support, but not Pattern Overrides. But since I couldn’t really think of one, maybe it’s fine to go ahead with this. Furthermore, AFAICT, the logic in your branch is pretty similar to this, so I guess both of us arrived at the same conclusion 😅 We’ll also have some time during the 7.0 cycle to tweak this some more, if needed. I had a quick look at the documentation changes in your PR, and I’d be happy to include them. Would you like to push a commit to this PR’s branch? Also, I’ll set the PR to “Ready for review” if you’d like to review/approve 😊 |
|
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. |
… overrides in dynamic blocks
Adds comprehensive documentation for:
- The block_bindings_supported_attributes filter for extending supported block attributes
- The block_bindings_supported_attributes_{$block_type} dynamic filter with examples
- How to access pattern override values in a dynamic block's render_callback
- Step-by-step guide with complete code examples for implementing pattern overrides in custom blocks
fabiankaegy
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pushed the docs and took this for a spin 🙂 Looks good to me in my testing 👍 From my end this is good to ship 🥳
| **Step 2: Access override values in your render callback** | ||
|
|
||
| The override values are stored in `$block->context['pattern/overrides']` as an associative array. The keys are block metadata names (assigned when enabling overrides), and the values are arrays of attribute overrides. | ||
|
|
||
| “`php | ||
| function my_block_render_callback( $attributes, $content, $block ) { | ||
| // Get the block's metadata name (set when enabling overrides) | ||
| $block_name = $attributes['metadata']['name'] ?? null; | ||
|
|
||
| // Get the pattern overrides from context | ||
| $overrides = array(); | ||
| if ( $block_name && isset( $block->context['pattern/overrides'][ $block_name ] ) ) { | ||
| $overrides = $block->context['pattern/overrides'][ $block_name ]; | ||
| } | ||
|
|
||
| // Get attribute values, preferring overrides when available | ||
| // Note: An empty string in overrides means "reset to default" | ||
| $title = $attributes['title']; | ||
| if ( isset( $overrides['title'] ) && $overrides['title'] !== '' ) { | ||
| $title = $overrides['title']; | ||
| } | ||
|
|
||
| $description = $attributes['description']; | ||
| if ( isset( $overrides['description'] ) && $overrides['description'] !== '' ) { | ||
| $description = $overrides['description']; | ||
| } | ||
|
|
||
| return sprintf( | ||
| '<div class="my-block"><h3>%s</h3><p>%s</p></div>', | ||
| esc_html( $title ), | ||
| esc_html( $description ) | ||
| ); | ||
| } | ||
| “` | ||
|
|
||
| **Key points to keep in mind:** | ||
|
|
||
| – **`uses_context`**: Your block must declare `pattern/overrides` in its `uses_context` to receive override data from parent Pattern blocks. | ||
| – **Block metadata name**: Each overridable block instance has a unique name stored in `$attributes['metadata']['name']`. This name is assigned when the user enables overrides on the block in the editor. | ||
| – **Empty string convention**: An empty string (`""`) in the overrides represents a reset to the default value. Your code should handle this appropriately. | ||
| – **Fallback behavior**: Always provide fallback values from `$attributes` in case the block is not inside a pattern or overrides are not set. | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@fabiankaegy Thank you for documenting this part — I hadn’t given much thought to it.
Reading it made me wonder though — it’s quite a lot a user has to do to use attribute values provided by Pattern Overrides. How about we implement this behavior in Gutenberg? I think we could check if pattern/overrides context is available for the current block, and if yes, iterate over it to set block attributes to the values provided.
Of the key points to keep in mind, the user would then only have to declare pattern/overrides in uses_context; the rest would happen automatically.
You wanna give that a try? Otherwise, I can have a go.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I like the idea of that. Let me tinker with it for a bit 👍
Of the key points to keep in mind, the user would then only have to declare pattern/overrides in uses_context; the rest would happen automatically.
I don’t see why we wouldn’t be able to also add that flag for them with the block type metadata filter 🤔 Will investigate 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought a bit more about it; it might not be totally straightforward using the filters available to us. (Out of render_block, render_block_data, and render_block_context, none has the “perfect” fit that allows us to modify attributes based on block context.)
Maybe it’s easier to do a proof-of-concept in Core, and then shoehorn it into those filters so we can add it to the GB compat layer based on that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Quick update, in my testing it looks like this is already working (with WP 6.9) 🎉
This can be seen e.g. through this test in wordpress-develop. Note that test/block is dynamic, with a render_callback that returns '<p>' . esc_html( $attributes['myAttribute'] ) . '</p>'.
In the test, $block->render() returns <p>This is the content value</p>, i.e. correctly uses the value provided by Pattern Overrides for myAttribute ✅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason why this works is that Pattern Overrides are really just an instance of Block Bindings, using the core/pattern-overrides source. The latter has uses_context set to pattern/overrides, which means that that context becomes available to all blocks that are bound to the pattern/overrides source. Block Bindings then takes care of setting bound block attributes to the values obtained from the source.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR to remove these instructions: #74749
…rver (#73889) Co-authored-by: ockham <bernhard-reiter@git.wordpress.org> Co-authored-by: fabiankaegy <fabiankaegy@git.wordpress.org> Co-authored-by: bph <bph@git.wordpress.org> Co-authored-by: colorful-tones <colorful-tones@git.wordpress.org> Co-authored-by: gziolo <gziolo@git.wordpress.org> Co-authored-by: mtias <matveb@git.wordpress.org> Co-authored-by: ndiego <ndiego@git.wordpress.org> Co-authored-by: talldan <talldanwp@git.wordpress.org> Co-authored-by: getdave <get_dave@git.wordpress.org> Co-authored-by: t-hamano <wildworks@git.wordpress.org> Co-authored-by: ryanwelcher <welcher@git.wordpress.org> Co-authored-by: cbravobernal <cbravobernal@git.wordpress.org>
What?
Identical to #72391.
In Patterns code, infer the list of blocks supported by pattern overrides from the server (instead of a hardcoded array).
Note that this would open pattern overrides for all block attributes that are supported by block bindings.
Closes #64870.
Why?
This is one of the instances where we were still keeping a separate, hard-coded list of blocks supported by pattern overrides on the client side.
Starting with #71820, we’ve been using the server side as the source of truth for the list of blocks (and block attributes) supported by block bindings; it is also exposed on the client side via private block context (see #72351).
The previous version of this PR, #72391, was closed since at the time, we concluded that the list of block attributes that should be supported by pattern overrides isn’t necessarily congruent with the list of block attributes that are supported by block bindings. Two examples given at the time are the Navigation Link and Navigation Submenu block’s
urlattributes.How?
PARTIAL_SYNCING_SUPPORTED_BLOCKSfromisOverridableBlock, and instead check againstObject.keys( select( blockEditorStore ).getSettings()?.__experimentalBlockBindingsSupportedAttributes || {} )from the callsites ofisOverridableBlock.hasOverridableBlocks(as that depended onisOverridableBlockand additionally worked recursively), and also perform the relevant checks inline.Testing Instructions
Verify that pattern overrides still work. For example,
(from #60721)