WordPress / gutenberg

The Block Editor project for WordPress and beyond. Plugin is available from the official repository.
https://wordpress.org/gutenberg/
Other
10.48k stars 4.18k forks source link

Block Bindings: context for supporting any block attribute #64189

Open SantosGuillamot opened 2 months ago

SantosGuillamot commented 2 months ago

Context

Adding support for any block attribute in block bindings has been in the roadmap since the beginning. However, there are some limitations we need to figure out first. That's why we started with the most common core blocks even though it is pretty limited. So far, it has helped us to shape the project, add value to the user, and start gathering feedback.

Until this is in place, we can keep adding support to specific block attributes if needed.

I'm opening this issue to share the limitations I see and start discussing them.

How block bindings API works

I believe this is important to understand why support for any block is not ready yet and what is needed.

Block bindings API works this way (summarized):

  1. It receives the HTML stored in the database.
  2. It gets the value from the specific source. The value of a custom field, for example.
  3. It replaces the relevant part of the HTML based on the attribute definition. For example, the image url corresponds to the attribute src: link. Or the paragraph content corresponds to the inner text of the P element: link.

Existing limitations / concerns

This is an initial list of the main topics we need to figure out before adding support for any block. Although I am sure more things will come up in the process.

HTML functionalities

Block Bindings API uses the HTML API to replace the HTML based on the value returned by the source. However, the HTML API is also relatively new and adding functionalities progressively. The main ones affecting the project:

We can hardcode these limitations for the currently supported blocks, but to open them to ANY block, we should have proper abstractions in place.

Conditional loading

In some blocks, the HTML saved on the database through the editor will vary based on the value of some attributes. For example, if we look at the image save file, we can see how it will rendered an A link element if href attribute exists, and it will add a FIGCAPTION element if the caption attribute is not empty.

Until now, this wasn’t a problem because the href and caption attribute values were expected to be the same in the editor and in the server. However, with block bindings, this is different because the attribute could be connected to a custom field (for example), which generates the value on the server.

Imagine I have an image with an empty caption in the editor, but connected to an existing custom field:

It happens the same the other way around. I could have a non empty caption in the editor, which will generate the FIGCAPTION element. But if in the server the value of the custom field is empty, I would like to remove it.

Again, for specific blocks, we can hardcode the solution, but it doesn't seem scalable.

As suggested here, one possible solution is to create a templating language that works both client-side and server-side. However, this needs to be explored further.

Lock attribute controls

When a block attribute is connected with block bindings, and the user can edit the value, we are locking the relevant controls. However, there is no direct link yet between block attributes and block controls, so it needs to be hardcoded now. This is an example of the image: link.

There is a related discussion for this and an experiment to make it work: link.

Define opt-in mechanism

We would need to create a mechanism to let blocks decide which attributes can use bindings and which ones do not. This will potentially require a new API and deciding what is the default behavior. We could create an “automatic opt-in” based on the block attribute definition, for example.


Any thoughts? Anything I am missing?

cbravobernal commented 2 months ago

I cannot find anything that hasn't been mentioned already.

My thoughts are that in a short-mid term, the common template language may not be viable, as it would cause a huge "developer learning" overload.

So, for Core, I guess our best option is to go block by block and see if we can reuse those conditionals. Ideally, we should keep things as they already are, and just replace data with block bindings in both editor and server at the same time. That way the logic behind rendering would be the same.

Thanks for writing this @SantosGuillamot , your insights are always super helpful 🚀

gziolo commented 1 month ago

Some updates to connect some other issues that touch on the same topic.

We would need to create a mechanism to let blocks decide which attributes can use bindings and which ones do not. This will potentially require a new API and deciding what is the default behavior. We could create an “automatic opt-in” based on the block attribute definition, for example.

There is a preliminary approach proposed for marking attributes as bindable:

Block Bindings API uses the HTML API to replace the HTML based on the value returned by the source. However, the HTML API is also relatively new and adding functionalities progressively. The main ones affecting the project:

While this is true for static blocks that save the content to the database, it appears to be non issue for dynamic blocks so we can offer a way for using Block Bindings earlier in these specific instances: