Skip to content
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

Block Bindings: context for supporting any block attribute #64189

Open
SantosGuillamot opened this issue Aug 2, 2024 · 2 comments
Open

Block Bindings: context for supporting any block attribute #64189

SantosGuillamot opened this issue Aug 2, 2024 · 2 comments
Labels
[Feature] Block bindings [Feature] Synced Patterns Related to synced patterns (formerly reusable blocks) [Type] Discussion For issues that are high-level and not yet ready to implement.

Comments

@SantosGuillamot
Copy link
Contributor

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:

  • Support for any HTML tag: In order to support any block, it needs to handle any markup. Hopefully, I believe this will be part of WordPress 6.7.
  • Support for CSS selectors: In some cases, the block attribute uses a CSS selector to specify which part of the HTML it corresponds to. For example, image href uses figure > a: link.
  • Provide HTML replacement functions: The HTML API will potentially provide methods to set_inner_html or set_outer_html. We need to use those methods to properly replace the HTML.

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:

  • The editor will save the HTML without the FIGCAPTION HTML element based on this conditional: link.
  • When block bindings logic runs and tries to replace the FIGCAPTION inner text with the value of the custom field in the server, it doesn’t exist, so it is not possible.
  • We would need to recreate the logic in the server to generate (or remove) the FIGCAPTION element if it doesn’t exist. You can see an example in this experimental pull request.

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?

@SantosGuillamot SantosGuillamot added [Type] Discussion For issues that are high-level and not yet ready to implement. [Feature] Block bindings labels Aug 2, 2024
@cbravobernal
Copy link
Contributor

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 gziolo added the [Feature] Synced Patterns Related to synced patterns (formerly reusable blocks) label Sep 9, 2024
@gziolo
Copy link
Member

gziolo commented Sep 9, 2024

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:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Block bindings [Feature] Synced Patterns Related to synced patterns (formerly reusable blocks) [Type] Discussion For issues that are high-level and not yet ready to implement.
Projects
None yet
Development

No branches or pull requests

3 participants