-
Notifications
You must be signed in to change notification settings - Fork 4.5k
Description
- Part of Block API #41236.
- Related to:
This tracking issue is meant to be used to discuss and shape the implementation of the Block Bindings API. Gathering the potential list of tasks and sharing progress on them.
Goal
This API aims to connect block attributes to values, obtained from different sources, that might vary depending on the context. For example, a value like post_author
that changes depending on the current post.
This will expand the capabilities of existing blocks without the need to create new ones, which will empower theme developers and site owners. For example, having a heading block with the content of the Post Author without needing a new Post Author block.
Why this API?
Working on connecting block attributes and custom fields triggered many discussions around whether the logic used there could be reused for other projects like Partially Synced patterns. After some proof of concepts and research, it seems that at least the Partially Synced patterns could benefit from the same abstraction. And it could be reused to connect to other sources like site data, external tools, shortcodes, or even other blocks. Additionally, they all share similar concepts, so, the same way the code can be reused, it may make sense to unify part of the UI to ensure everything is coherent.
Hence, this new Block Bindings API.
Projects that will benefit from this API
As mentioned above, there are some ongoing initiatives that I believe could benefit from this API:
For discussing these projects, please refer to their respective issues. There might be more projects that I’m not aware of that could use it, so please share them here, and I can include them in this list.
Additionally, I feel this could be useful for other future projects as well.
How does the API work technically?
Until now, we have been working on this API as part of the Custom Fields project, and there are some proof of concepts already in place.
I like to think about the API as a three steps process:
- Create a binding between block attributes and a source.
- Get the value from the source defined in the binding.
- Update the HTML using the value obtained from the source.
1. Create a binding between block attributes and a source.
This can be done via a “bindings” object that contains the relevant information.
"bindings": {
"content": {
"source": "meta_fields",
"key": "post_author"
}
}
2. Get the value from the source defined in the binding.
Depending on the source, the value will be obtained from a different place using PHP. For example, in the case of the meta_fields
source, it will use the get_post_meta
function, while a hypothetical shortcode
source could use the do_shortcode
function.
Each source will take care of its logic.
Additionally, although there will be core sources like “meta_fields”, developers should have a mechanism to add their custom sources.
Some sources on top of my mind that I believe could be useful:
- Meta fields: These could include post fields or custom fields.
- Site data: To show fields like Site Title, site URL, etc.
- User data: To show fields related to the current user like user name, user email…
- Pattern: Partially Synced Patterns will likely need a custom source for them.
- Block: To get the attributes from other blocks, probably using an ID.
- Shortcode: To show the result of a shortcode.
- Any external tool using Gutenberg: If other tools, like Drupal, adopt Gutenberg, they could bind blocks to their own sources.
3. Update the HTML using the value obtained from the source.
Once we have the value from the source, we can update the relevant part of the HTML with the block attribute selectors and the HTML API. For example, if it is bound to the paragraph content, it knows it has to replace the inner content, while if it is linked to the image URL, it knows it has to replace the src
attribute.
Progressive enhancement
The idea is to embrace progressive enhancement for developing this API and the projects using it. We can start by limiting this functionality to specific core blocks (like paragraph and image), testing how it works, and keep iterating.
We can add support for more blocks progressively. Once we feel confident enough, we can expand it and allow any block from any developer to use this API.
Also, we could explore later the possibility of supporting some of the other sources shared above.
HTML API Dependency
As explained above, this API will rely on the HTML API. Because of that, it’s important to note that the HTML API is still a work in progress. It already offers great APIs to be used here, but there are some limitations right now as well that prevent us from allowing to connect some of the block attributes.
I’ve been taking a look at the current core blocks, and it seems these are the missing functionalities to support ALL of them:
- Support to mutate HTML to change the inner content of an element. Until we have a set_inner_markup function, we can manually mutate the HTML for our experiments.Support for the PRE HTML element.Support for CSS selectors.Support for H1, H2, H3, H4, H5, H6 HTML elements.Support for lists (OL, UL, LI) HTML elements.Support for CITE HTML element.Support for table (TABLE, THEAD, TBODY, TFOOT, TD, TH) HTML elements.To pick up a draggable item, press the space bar. While dragging, use the arrow keys to move the item. Press space again to drop the item in its new position, or press escape to cancel.
A group of contributors is working on this, so I’ll try to keep this list updated once support is added. Support for the blocks that depend on this can be added progressively whenever it is ready.
Once the HTML API is mature enough and covers most of the use cases, we can promote this to be used not only by core blocks but also by any block. Until then, we cannot ensure that the HTML API can parse the HTML of external blocks because we are unaware of their structure. For example, if they are using a CITE
element and that’s not supported, it wouldn’t work.
Progress
WordPress 6.5
- Set up the basics to enable other projects like the Custom Fields or Patterns to build on top of it.Create a proper mechanism to add new sources, even if this first version is limited to
metadata
andpattern
.Decide the syntax of the API.Mechanism to change the HTML in the frontend depending on the block attribute source.- For
attribute
source we need to change the HTML attribute depending on the selector. - For
html
source we need to change the HTML inner content. For that, we might need to implement aset_inner_markup
private function.
To pick up a draggable item, press the space bar. While dragging, use the arrow keys to move the item. Press space again to drop the item in its new position, or press escape to cancel.Add tests.To pick up a draggable item, press the space bar. While dragging, use the arrow keys to move the item. Press space again to drop the item in its new position, or press escape to cancel.
Future releases
This is a list of things to consider/questions related to the Block Bindings API that will be updated as we go along:
- Allow external developers to add support for other sources.Analyze how to support styles as block attributes.Should we provide a way/property to allow users to change the format of the obtained value? (link).Should the block bindings work in the frontend?To pick up a draggable item, press the space bar. While dragging, use the arrow keys to move the item. Press space again to drop the item in its new position, or press escape to cancel.
Activity
SantosGuillamot commentedon Sep 18, 2023
In order to approach this and start shaping the API, I believe we can work on the related ongoing projects and polish the API based on their needs.
For this initial phase, I propose focusing on achieving the following:
This way, we would have a controlled environment while opening up many possibilities, as I consider those blocks will highly benefit from this.
After that, we can work on supporting more blocks progressively and adding support for more complex attributes like styles or other sources if needed.
blockHooks
in a block with a save function. #54796setBlockAttributes
to updatedynamicContent
#54233gziolo commentedon Oct 3, 2023
The most recent prototype for Partially Synced Patterns #54233 is implementing a modification on the block editor store's level to allow dynamic content inside the
setBlockAttributes
action. This is also where the Block Bindings API could operate by intercepting the modifications that would previously happen on the block level.SantosGuillamot commentedon Nov 13, 2023
For 6.5, there are plans to include an initial version of:
Both projects will use the Block Bindings API under the hood, so that means we need to ship a working version of it.
Things to consider
These are some of the initial things we need to consider for 6.5, although we will edit this issue once we progress and discover what other things we need to do.
metadata
andpattern
.attribute
source we need to change the HTML attribute depending on the selector.html
source we need to change the HTML inner content. For that, we might need to implement aset_inner_markup
private function.I've updated the opening post to reflect this
getdave commentedon Nov 20, 2023
@SantosGuillamot Could this be used say, to bind a Navigation block link item to it's original Post "source"?
So if I create a link to "My Sample Post", could I use the bindings API to ensure the link stays in sync with changes to "My Sample Post" (both in the Editor and on the front of the site)?
43 remaining items