#60282 closed enhancement (fixed)
Add the Block Bindings API, including the "post_meta" and "pattern" sources
Reported by: | czapla | Owned by: | youknowriad |
---|---|---|---|
Milestone: | 6.5 | Priority: | normal |
Severity: | normal | Version: | |
Component: | Editor | Keywords: | has-patch has-unit-tests needs-dev-note |
Focuses: | Cc: |
Description
Introduce the Block Bindings API for WordPress.
This includes 2 sources for block bindings:
- post meta
- patterns
Change History (41)
This ticket was mentioned in PR #5888 on WordPress/wordpress-develop by @czapla.
8 months ago
#1
- Keywords has-unit-tests added
@talldanwp commented on PR #5888:
8 months ago
#2
The API allows developers to connects block attributes to different sources. In this PR, two such sources are included: "post meta" and "pattern".
An option could be to consider a separate backport PR for the 'pattern' source, as I think there's also a little bit of extra code needed to set up the block context for pattern overrides. Let me know what you think.
@artemiosans commented on PR #5888:
8 months ago
#3
Summarizing my comments, we could further simplify what gets exposed as a public API for v1. We should consider moving two functions to WP_Block class as private methods:
- wp_block_bindings_replace_html
- _process_block_bindings
@gziolo Ok I addressed this in https://github.com/WordPress/wordpress-develop/pull/5888/commits/9303e02f1c755256fd5011250cd754ed6bf9ccd4. But we still need to expose the processing somehow, right? I added a wrapper function process_bindings
to the class so we can still access the logic.
Which leads me to the next observation, that we should follow the established pattern and rename the method to align:
function register_block_binding( $name, $properties )
If we follow other registration helpers, the class name would better fit as:
WP_Block_Bindings_Registry
Ok I've updated the class name and renamed the methods in https://github.com/WordPress/wordpress-develop/pull/5888/commits/30f4ed76f41be76c0cb929e883176ad98ec11312. However, I don't think we can go with just register_block_binding
because technically, a _binding_ is the act of connecting a block's attribute to a source in the editor, and what we're doing here is registering the source to facilitate that connection. I think it would be good to continue making that distinction to keep things simple to understand.
@artemiosans commented on PR #5888:
8 months ago
#4
Also, the latest changes will break the tests, so we need to update those.
@artemiosans commented on PR #5888:
8 months ago
#5
Hi all! I believe I've addressed all of the outstanding issues up to now except for the following:
- Refactoring the processing of block bindings into two steps as discussed here. I think this one can be handled in a separate PR.
- Refactoring to use post ID from the block context, which seems it may require more discussion and could be handled separately as well (discussion 1) (discussion 2)
- Potentially remove manual check for supported blocks and properties in the future, as per usage of the HTML API sometime in the future (discussion)
It seems there's still some discussion to be had on the structure of the bindings object and naming of certain methods as well, namely register()
which I can follow up on next week.
Am I missing anything? Let me know what you all think, thanks! 🙏
This ticket was mentioned in PR #5965 on WordPress/wordpress-develop by @gziolo.
8 months ago
#6
Trac ticket: https://core.trac.wordpress.org/ticket/60282
8 months ago
#8
Committed with https://core.trac.wordpress.org/changeset/57373.
8 months ago
#9
I landed the WP_Block_Bindings_Registry
class with https://core.trac.wordpress.org/changeset/57373. Let's update the branch to reflect it.
This ticket was mentioned in PR #5966 on WordPress/wordpress-develop by @gziolo.
8 months ago
#10
Trac ticket: https://core.trac.wordpress.org/ticket/60282
8 months ago
#12
Committed with https://core.trac.wordpress.org/changeset/57375.
8 months ago
#13
I also landed register_block_bindings_source
, unregister_block_bindings_source
and get_all_registered_block_bindings_sources
with functions with https://core.trac.wordpress.org/changeset/57375.
8 months ago
#16
~An option could be to consider a separate backport PR for the 'pattern' source, as I think there's also a little bit of extra code needed to set up the block context for pattern overrides. Let me know what you think.~
Actually, this changed recently, there are now no backports for pattern overrides other than the registration of the binding source.
Thanks for the update @talldan 🙏
8 months ago
#17
The tests are passing now and I believe all of the feedback has been addressed.
Summary of the updates:
- Incorporate the changes from https://github.com/WordPress/gutenberg/pull/58337/files into this PR
- Update the unit tests and add ones that test passing arguments to
get_value_callback()
. - Updates to the docstrings to explain the format of the source name (f2a611b)
As previosly mentioned by @artemiomorales, the following can be handled in follow-up PRs:
- Refactoring the processing of block bindings into two steps as discussed https://github.com/WordPress/wordpress-develop/pull/5888#discussion_r1462922587. I think this one can be handled in a separate PR.
- Refactoring to use post ID from the block context, which seems it may require more discussion and could be handled separately as well (https://github.com/WordPress/wordpress-develop/pull/5888#discussion_r1461571508) (https://github.com/WordPress/wordpress-develop/pull/5888#discussion_r1463100836)
- Potentially remove manual check for supported blocks and properties in the future, as per usage of the HTML API (https://github.com/WordPress/wordpress-develop/pull/5888#discussion_r1462909865)
cc @artemiomorales @SantosGuillamot @gziolo
@artemiosans commented on PR #5888:
8 months ago
#18
During my testing, I realized that pattern overrides are no longer working on this branch or on trunk
. I haven't been able to look into identifying the cause yet, though it may be getting addressed by this PR on the Gutenberg side:
#20
@
8 months ago
I opened an issue on Github about Standardizing data access for blocks on the server in place of my previous comment.
@talldanwp commented on PR #5888:
8 months ago
#21
During my testing, I realized that pattern overrides are no longer working on this branch or on trunk. I haven't been able to look into identifying the cause yet, though it may be getting addressed by this PR on the Gutenberg side:
It could be that. A lot of the pattern overrides code also resides in the block library package in gutenberg, so a package update for wordpress core might also be required (and then this branch rebased).
There were quite a few last minute PRs added to the last Gutenberg release.
8 months ago
#22
The unit tests are failing because Tests_WP_Customize_Widgets::test_get_selective_refreshable_widgets_when_no_theme_supports
test calls $this->do_customize_boot_actions();
which calls do_action( 'init' );
.
Because of this, the init
action is fired twice and this check fails.
If understand correctly, init
could be fired multiple times per request on a site under some circumstances (which is what happens here). Block registration has a similar check.
I'm not sure what the right behavior here should be. I see these options:
- For the bindings that ship in core (
post-meta
&pattern
), always unregister any bindings with the same name. - Remove the
_doing_it_wrong()
altoghether.
What do you think @youknowriad @gziolo ?
8 months ago
#23
The following diff should resolve the issue that exists only in the test env:
-
tests/phpunit/includes/functions.php
diff --git a/tests/phpunit/includes/functions.php b/tests/phpunit/includes/functions.php index 81d4339db1..0fdff9c71a 100644
a b tests_add_filter( 'send_auth_cookies', '__return_false' ); 339 339 * @since 5.0.0 340 340 */ 341 341 function _unhook_block_registration() { 342 // Block types. 342 343 require __DIR__ . '/unregister-blocks-hooks.php'; 343 344 remove_action( 'init', 'register_core_block_types_from_metadata' ); 344 345 remove_action( 'init', 'register_block_core_legacy_widget' ); 345 346 remove_action( 'init', 'register_block_core_widget_group' ); 346 347 remove_action( 'init', 'register_core_block_types_from_metadata' ); 348 349 // Block binding sources. 350 remove_action( 'init', '_register_block_bindings_pattern_overrides_source' ); 351 remove_action( 'init', '_register_block_bindings_post_meta_source' ); 347 352 } 348 353 tests_add_filter( 'init', '_unhook_block_registration', 1000 );
It will never be the case in the production code.
#24
@
7 months ago
- Owner set to youknowriad
- Resolution set to fixed
- Status changed from new to closed
In 57514:
@youknowriad commented on PR #5888:
7 months ago
#25
Thanks all, commit https://core.trac.wordpress.org/changeset/57514
This ticket was mentioned in PR #6016 on WordPress/wordpress-develop by @gziolo.
7 months ago
#26
Trac ticket: https://core.trac.wordpress.org/ticket/60282
#27
@
7 months ago
- Resolution fixed deleted
- Status changed from closed to reopened
Reopening as there are still issues to fix like the bug discussed in this thread: https://github.com/WordPress/wordpress-develop/pull/5888#discussion_r1475692597.
@youknowriad commented on PR #6016:
7 months ago
#28
Thanks for handing the follow-up @gziolo I appreciate it. On a quick glance, everything looks good to me.
7 months ago
#30
Committed with https://core.trac.wordpress.org/changeset/57526.
This ticket was mentioned in PR #6029 on WordPress/wordpress-develop by @czapla.
7 months ago
#31
This PR improves the inline documentation for the Block Bindings API.
It also implements a minor improvement from https://github.com/WordPress/wordpress-develop/pull/5888#discussion_r1476793062. The values passed to $processor->set_attribute()
should not be escaped.
7 months ago
#32
Maybe it's enough to put there @see register_block_bindings_source annotation. I left two suggestions to discuss further before I commit changes.
That makes sense. I also added a note in 94385a524085363cdd07b9870109123e2601a63c saying it's a low-level method and register_block_bindings_source()
should be used in most cases instead.
This ticket was mentioned in PR #6059 on WordPress/wordpress-develop by @czapla.
7 months ago
#36
This PR refactors the processing of block bindings into 2 steps.
#### Before
process_block_bindings()
takes the $block_content
as input and:
- Gets the value for each "bound" attribute from the respective source.
- For each updated attribute calls
replace_html()
to get the updated$block_content
filled in with the values from the updated attributes.
#### Now
process_block_bindings()
doesn't take any input
- Gets the value for each "bound" attribute from the respective source.
- Returns the updated attributes with values from the sources.
- The updated attributes are used in the
render()
function of the block wherereplace_html()
is called with the updated attributes.
Trac ticket: https://core.trac.wordpress.org/ticket/60282
7 months ago
#38
Committed with https://core.trac.wordpress.org/changeset/57574.
7 months ago
#40
Currently the binding process is completely on, nether $block_content = $this->process_block_bindings( $block_content ); or $modified_block_content = $this->replace_html are filtered. Is it too soon to consider filters? Maybe it is.
@draganescu, we could always discuss introducing new settings for the block binding source:
filter_callback
to post-process the raw value returned by the source, example: date formatting.should_replace_callback
to run before$this->replace_html()
that would let folks decide whether to replace the value for an attribute in HTML.
We should be iterating on the public API as we learn about the most common needs reported by developers.
More information about the Block Bindings API: https://github.com/WordPress/gutenberg/issues/54536
Trac ticket: https://core.trac.wordpress.org/ticket/60282
This PR introduces the Block Bindings API for WordPress.
The API allows developers to connects block attributes to different sources. In this PR, two such sources are included: "post meta" and "pattern". Attributes connected to sources can have their HTML replaced by values coming from the source in a way defined by the binding.
On a technical level, the way the API works is a 3-step process:
### 1. Create a binding
The bindings have the following structure:
_An example binding for the
content
attribute of Paragraph block and theurl
attribute of the Image block.Both using the
post_meta
source._This PR does not include any UI for adding those
metatada
attributes to blocks at the moment. This is intentional as the API is meant as a building block and such UI will be developed later.### 2. Get the value
This PR includes a mechanism for registering "sources" for the block bindings. A "source" defines where to get a value for the binding from. Two sources are included in this PR:
Each source is responsible any logic required to obtain the value from a source.
### 3. Update the HTML
At runtime, the HTML API is used to update the HTML of the block with values from the block binding sources. At the moment, a limited and hardcoded number of blocks and attributes is supported in this PR:
$allowed_blocks = array( 'core/paragraph' => array( 'content' ), 'core/heading' => array( 'content' ), 'core/image' => array( 'url', 'title', 'alt' ), 'core/button' => array( 'url', 'text' ), );