-
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.
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.
- For
- Add tests.
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?