WordPress / gutenberg

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

Tracking issue: Block bindings API #60954

Open SantosGuillamot opened 4 months ago

SantosGuillamot commented 4 months ago

Part of https://github.com/WordPress/gutenberg/issues/41236 overview issue. Originally proposed at https://github.com/WordPress/gutenberg/issues/51373.

Before this issue, the project was mainly discussed and implemented here.


This tracking issue is meant to be used to discuss the strategy of the Block Bindings API. The implementation details or APIs should be discussed in their relevant issues.

It also includes a complete list of related tasks. The idea is to create different iteration issues (for each WordPress release, for example) and handle them progressively.

We'll post updates each time a new iteration is created or finished. You can subscribe to the different iterations for more regular updates.


Goal of the block bindings API

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.

How the API works

I think it makes sense to differentiate between

Bindings creation

To create a binding of a block attribute and an external source, users should add a "bindings" object in the "metadata" attribute with the relevant information.

"metadata": {
    "bindings": {
        "content": {
            "source": "core/post-meta",
            "args": {
                "key": "custom_field"
            }
        }
    }
}

Each source could have different arguments depending on their needs.

Additionally, the idea is to create a UX that easily adds this object directly thorugh the interface. It must be extendable to cover the different sources' needs.

What happens in the server

If a block has the "bindings" object, there are two steps happening in the server:

1. Get the value from the source defined in the binding.

Using the provided APIs, each source must define how to get the appropriate value. For example, in the case of the meta_fields source, it could use the get_post_meta function, while other sources might need something different.

2. 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.

What happens in the editor

When a "bindings" object is found in a block in the editor, there are two different scenarios:

1. Allow editing of the external source

The idea is to provide the possibility of directly editing the value of the external source through the block interface. This means that, if a paragraph content is connected to a custom field, when you edit the RichText you are actually editing the value of the custom field and not the content of the paragraph.

2. Lock editing

Depending on each source, they might want to lock the editing of the external source and just lock the editing. This could happen when the user is in a template or when they don't have permission to edit the external source, for example.

As each source will have different needs, they should be the ones deciding when to lock it using the provided APIs.

Core sources

As mentioned, apart from providing the mechanism to allow users to create their own sources, there will be some core sources added by default. Some examples of this could be:

Feel free to suggest other sources that should be considered here.

Supported blocks

The idea is to allow any block to opt-in for the block bindings API and make any block attribute available. However, the server logic relies on the HTML API, which is still a work in progress at the time of this writing. Because of that, we will add support for core blocks progressively until we consider it safe to open it for any block.

These are the block attributes supported so far:

Please share any block you consider important and not supported yet.

Resources

These are some resources published that can help to understand the Block Bindings API better:

Roadmap

This is the list of tasks that we currently have in mind for the block bindings API. We will update this list as we progress and learn more about this initiative's needs.

The idea is to create different iteration issues (for each WordPress release, for example) and handle them progressively.

We'll post updates each time a new iteration is created or finished. You can subscribe to the different iterations for more regular updates.

SantosGuillamot commented 4 months ago

I've just created an iteration for WordPress 6.6. These are the tasks that we can expect to work on during this release cycle.

As previously mentioned, the main focus will be to allow editing in the existing core sources.

Bindings creation Even though we'll probably won't add a UI to create bindings yet, we'd like to start discussing how it should work.

Server APIs

Editor APIs

Core sources

richtabor commented 3 months ago

Define how to work with placeholders.

I question if it should be front-and-center within placeholders. Or instead more like overrides, within the "Advanced" panel—at least initially, for selecting a source and key. Could potentially use a modal just like overrides.

I'm a bit cautious of putting something more developer-oriented in such a prominent position within the placeholder. And if we do something like overrides does, we would not need both a UX for placeholder state and for post-placeholder. It could be one experience, across any blocks.

SantosGuillamot commented 1 month ago

Now that WordPress 6.6 is almost here, I've closed the current iteration and opened a new one for 6.7.

WordPress 6.6 update

Most of the functionalities expected for 6.6 landed in time. Among other things, it includes the possibility of editing the value of the custom fields directly from the connected blocks:

https://github.com/WordPress/gutenberg/assets/34552881/05dab9b1-5759-4ce6-b97e-0fb827253cae

You can find a more detailed list of what was included, as well as more demos, in this comment and in the core note.

New iteration for WordPress 6.7

I have just created a new iteration for 6.7, which will be used to share regular updates and track progress. Let's use it for discussing topics related to it.

As explained there, the initial idea is to focus on:

asafm7 commented 1 month ago

Is this the place to suggest Block Binding support for the Embed block?

SantosGuillamot commented 1 month ago

There is this related issue where people are sharing what blocks to support for synced pattern overrides and block bindings. It might be good to share your opinion there as well to get a better understanding of which blocks are considered more important and why?

haszari commented 2 weeks ago

To use block bindings, first you need to define and expose some custom meta fields. Currently this has to be done via PHP. As I understand it, there's no UI in WordPress core to set a custom meta field on a post, that can be bound to a block – is that accurate?

I'm interested in that possibility – allowing users to add custom metadata to posts, and then use that data in block-powered layouts. I'm hoping this is in the core roadmap somewhere.

Does this issue include scope for adding, editing custom meta fields, and exposing/registering so they can be used in blocks? Keen to follow progress, if there's an issue or a roadmap item please link me to it.

annezazu commented 2 weeks ago

Hey there @haszari! Great questions. The best next place to look is the iteration issue for 6.7 for block bindings. This is a scoped issue for targeted items for the 6.7 release. As part of that check out a recent update from four days ago that includes a demo of a UI to create bindings in the editor itself. . You can expect an iteration issue for each subsequent release going forward to help track and follow progress outside of these larger tracking issues that cover larger bodies of work.

haszari commented 1 week ago

Awesome, thanks @annezazu – will follow along there :)

haszari commented 1 week ago

Polish and open block bindings editor’s APIs for extenders: Core sources like "Post Meta" use some private APIs to handle bindings in the editor. The idea is to polish those APIs to enable external developers to use them.

Clarifying one point – @annezazu does that issue cover adding a UI for adding/editing custom metadata fields (e.g. on a post). The part that I'm confused about is how to set up the source data to bind to.

I had imagined that any custom meta fields would work, and that I'd be able to add arbitrary custom meta to a post using WordPress core only, no plugins or custom code. Is this something that's in the roadmap, for 6.7 or further on?

As I understand it, these block bindings can only use data from custom plugins – if I'm running vanilla WordPress, and want to add an extra field to each post (from UI), how do I do that? I have a vague memory pre-Gutenberg of arbitrary metadata fields in the (old) post editor, is there a replacement for that, or a better way to do it?

SantosGuillamot commented 1 week ago

If I am understanding you correctly, creating custom fields is slightly different and not covered by block bindings. Block bindings connect block attributes and dynamic sources, including custom fields. However, how those custom fields are created is a different topic, and it feels a bit more complex.

Right now, new custom fields are dynamically registered during the server processing. You need to have a PHP function running register_post_meta. In the future, WordPress might include a UI for that, maybe using Data Views, but it could get tricky. Once the proper mechanisms are in place, we might want to explore reusing them as well in the block bindings UI somehow, but that is a bit unclear to me at this point.

haszari commented 1 week ago

If I am understanding you correctly, creating custom fields is slightly different and not covered by block bindings. Block bindings connect block attributes and dynamic sources, including custom fields. However, how those custom fields are created is a different topic, and it feels a bit more complex.

Exactly – yes, they are separate, but related! I'm keen to help figure out the complexity of registering and editing custom metadata, which would make this whole system much more powerful and amazing!