WordPress / gutenberg

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

Connecting block attributes and custom fields & Block Bindings API for WP 6.5 #53300

Closed SantosGuillamot closed 4 months ago

SantosGuillamot commented 1 year ago

Part of:

Related to:


EDIT: Connecting block attributes and custom fields, and the block bindings API tracking issues have been merged into this epic because they are highly related and it seems it is easier to follow having everything under the same discussion.

This issue is meant to keep track of and discuss how to connect block attributes with custom/meta fields and how Block Bindings API should work. It includes a list of tasks needed for this, and we will share updates about the progress here.

For more context about the reasoning of the block bindings API, you can take a look at its original tracking issue.

Progress

This is a list of things to consider/questions related to the Block Bindings API that will be updated as we go along:

WordPress 6.5 release process

Click to see the list of issues addressed during 6.5 release cycle --- A couple of things that are important: * **This project depends on the Block Bindings API**: [link](https://github.com/WordPress/gutenberg/issues/54536). * **We will start supporting just a few core blocks attributes** that can be increased in a later phase. We can start with: * Paragraph content. * Heading content. * Image URL. * Button link and content. ### Fixes/updates for Gutenberg 17.6 RC (Tuesday 30th) - [x] Decide the final name of the public class and methods included in [this pull request](https://github.com/WordPress/wordpress-develop/pull/5888). - [x] Migrate all the changes suggested in [this wordpress-develop pull request](https://github.com/WordPress/wordpress-develop/pull/5888) to Gutenberg, including the naming decision. [#58383](https://github.com/WordPress/gutenberg/pull/58383) - [x] Decide the final shape of the bindings object used in the blocks and make the necessary changes: [#58337](https://github.com/WordPress/gutenberg/pull/58337) - [x] Backports to WordPress. - [x] Add more tests for the bindings, especially in the editor. - [x] Add validation in the `WP_Block_Bindings_Registry` class like others like `WP_Block_Type_Registry` are doing: [link](https://github.com/WordPress/wordpress-develop/blob/2526eab870476dd825758ead7cc48ddccfede138/src/wp-includes/class-wp-block-type-registry.php#L48-L100). ### Fixes/updates for WordPress 6.5 beta 1 (February 13th) - [x] Review the accessibility of the editor with the accessibility team, including the suggestions made: [link](https://github.com/WordPress/gutenberg/issues/58595). - https://github.com/WordPress/gutenberg/pull/58687#pullrequestreview-1867359839 - [x] Migrate to Gutenberg the changes made in this core pull request: [link](https://github.com/WordPress/wordpress-develop/pull/6016). PR: [#58683](https://github.com/WordPress/gutenberg/pull/58683) - [x] Fix a bug with `strcasecmp` reported [here](https://github.com/WordPress/wordpress-develop/pull/5888#discussion_r1475692597). - [x] Decide if we should add a `WP_Block_Binding_Source` class and handle validation there: [link](https://github.com/WordPress/gutenberg/pull/58337#discussion_r1469227481). PR: [#6042](https://github.com/WordPress/wordpress-develop/pull/6042) / Core changeset: [57562](https://core.trac.wordpress.org/changeset/57562) - [x] Refactoring the processing of block bindings into two steps: [link](https://github.com/WordPress/wordpress-develop/pull/5888#discussion_r1462922587). This would solve [this issue](https://github.com/WordPress/gutenberg/issues/58425) with the empty images in pattern overrides. PR: [#6059](https://github.com/WordPress/wordpress-develop/pull/6059) - [x] Add initial documentation. Core changeset: [57560](https://core.trac.wordpress.org/changeset/57560) - [x] Remove unused `setAttributes`. PR: [#58806](https://github.com/WordPress/gutenberg/pull/58806) - [x] Lock editing by default when the source used in the bindings is not registered in the client and adapt pattern overrides. PR: [#58787](https://github.com/WordPress/gutenberg/pull/58787) ### Fixes/updates during beta phase - [x] Fix the way context is added as discussed [here](https://github.com/WordPress/gutenberg/pull/58554). [Core](https://github.com/WordPress/wordpress-develop/pull/6079) / [Gutenberg PR](https://github.com/WordPress/gutenberg/pull/58554) - [x] Remove unnecessary `queryId` in context: [link](https://github.com/WordPress/gutenberg/commit/fd467521e4ddca70cc7bcd33f6719a0d507cbd52#r137779780). Solved as part of [Core](https://github.com/WordPress/wordpress-develop/pull/6079) / [Gutenberg PR](https://github.com/WordPress/gutenberg/pull/58554) - [x] Create a guide about using block bindings. Discussion: [219](https://github.com/WordPress/developer-blog-content/discussions/219). Guide [part 1](https://developer.wordpress.org/news/2024/02/20/introducing-block-bindings-part-1-connecting-custom-fields/). - [x] Fix metadata attribute not being preserved after block transforms: [link](https://github.com/WordPress/gutenberg/issues/59086). PR: [#59179](https://github.com/WordPress/gutenberg/pull/59179) - [x] Fix query loop not working as expected in the editor when blocks are bound. PR [#59283](https://github.com/WordPress/gutenberg/pull/59283) - [x] Improve the accessibility of the block bindings: - https://github.com/WordPress/gutenberg/issues/58674 - https://github.com/WordPress/gutenberg/issues/58673 - [x] Review the `use-bindings-attributes` hook and improve its implementation. As part of that, we should address [link](https://github.com/WordPress/gutenberg/pull/58085#discussion_r1464611692). PR with the refactoring: [#58895](https://github.com/WordPress/gutenberg/pull/58895/) - [x] Fix insert button when pressing enter in bound blocks. [#59361](https://github.com/WordPress/gutenberg/pull/59361) - [x] Don't show protected meta fields. PR [#59326](https://github.com/WordPress/gutenberg/pull/59326) / Core ticket [#59326](https://core.trac.wordpress.org/ticket/60651) - [x] [Dev note](https://make.wordpress.org/core/2024/03/06/new-feature-the-block-bindings-api/) covering how extenders can use the block bindings. - [x] Review the current UX and make further improvements: [link](https://github.com/WordPress/gutenberg/issues/58978). - https://github.com/WordPress/gutenberg/pull/59185 - https://github.com/WordPress/gutenberg/pull/59434 - https://github.com/WordPress/gutenberg/pull/59477

WordPress 6.6 planning

This section will be used to keep track of the issues that could potentially be addressed for WordPress 6.6.

As explained in this comment, the idea is to keep the scope limited and work on more functionalities if there is time at the end of the release cycle.

Initial plan

Keep in mind that this is not set in stone and it might change. The initial idea is to focus on these aspects:

Polish the existing code

And work on new aspects like:

Out of scope for 6.6

Trying to keep the scope limited for this short release, the idea is to work on these functionalities only once the previous points are finished:

SantosGuillamot commented 7 months ago

Can a connection be defined by a theme?

It totally can. In the end, bindings are just an attribute we are adding to the block, so it is part of the HTML. If a theme wants to create a binding in a template they could do something like:

<!-- wp:paragraph {"metadata":{"bindings":{"content":{"source":{"name":"post_meta","attributes":{"value":"custom_field"}}}}}} -->

They shouldn't need a filter for that if I am not mistaken.

BITS: It feels like this functionality would also help with this problem? Has that been considered?

Yes, we have considered that functionality as well and we believe it can help power the bindings in the future. On the other hand, it seems that feature requires a deeper research and development, so I believe it makes sense to start with this approach, which cover other use cases as well, and analyze later how to integrate both of them.

michalczaplinski commented 7 months ago

It totally can. In the end, bindings are just an attribute we are adding to the block, so it is part of the HTML. If a theme wants to create a binding in a template they could do something like:

Right! That's absolutely true 🙂 I assumed (perhaps incorrectly) that the question was about adding a binding to all blocks of a certain type!

SantosGuillamot commented 7 months ago

Update

During the last weeks, there has been good progress on the project:

Done

Next steps

SantosGuillamot commented 7 months ago

Update

A new update with the things that were included in the last Gutenberg release and will be available for testing after the RC:

I recorded this video with its current status in trunk:

https://github.com/WordPress/gutenberg/assets/34552881/ed62013e-692c-45c8-849c-3a1a74f4224f

Next steps

Progress and updates relative to these tasks will be shared in the opening post.

After working on those pull request, we have identified some remaining decisions/tasks that need to be addressed ideally before making the APIs public:

Fixes/updates during this RC (until next Tuesday 30th)

Improvements for next RC (February 9th)

Could be done during beta phase

I believe, and correct me if I am wrong, that these improvements to the code could be done during beta phase:

Out of the scope for 6.5

I'd like to include as many things as possible in 6.5, but trying to be realistic, I believe this list will probably not make it:

gaambo commented 7 months ago

Decide the final shape of the bindings object used in the blocks and make the necessary changes.

My comment is based on the current structure from https://github.com/WordPress/wordpress-develop/pull/5888:

// These are block attributes
{
    "metadata": {
        "bindings": {
            "content": {
                "source": {
                    "name": "post_meta",
                    "attributes": {
                        "value": "text_custom_field"
                    }
                }
            }
        }
    }
}

To avoid confusion, I would suggest renaming attributes to settings or something like that. I think it could be misunderstood that that's something to do with attributes. Maybe something like:

{
    "metadata": {
        "bindings": {
            "content": {
                "source": "post_meta",
                "key": "text_custom_field",
                "settings": {
                    "placeholder": "",
                    "prefix":"",
                    "postfix":""
                    [...] // other settings a custom source could implement
                }
            }
        }
    }
}

It's probably something minor in the grand scheme of things of this feature 😅 But we all know naming is hard, and avoiding using a word like "attributes" for different meaning would be great.

Another question is, how would that work with settings that span across multiple block attributes. For example, the core/image block has id and url (as well as alt).

As far as I can see, the block edit function has to implement a check for a binding itself and then lock the controls for it. I guess, for now, there's no other solution, because controls can be used very flexible (also outside of blocks) and there's no structured connection between rendered controls and attributes. But that also means, that - in the future when this feature/API is public - even when I add the binding for an attribute to a block, I can't be sure the block "supports" it and locks the control - am I right?

carolinan commented 7 months ago

Can we please include documentation in the planning for the RC? It is not insignificant neither in time or effort and it is needed for testing the feature.

SantosGuillamot commented 7 months ago

Thanks a lot for sharing your feedback, @gaambo !

I must say that I'm aligned with your thinking and what you mention is something that has been considered. It's been one of the main reasons I included the point: "Decide the final shape of the bindings object used in the blocks and make the necessary changes.".

What I had in mind was something like this:

{
    "metadata": {
        "bindings": {
            "url": {
                "source": "core/post-meta",
                "args": {
                    // All arguments defined by each source
                    "key": "url_custom_field",
                    ...
                }
            },
           "alt": {
                "source": "core/post-meta",
                "args": {
                    "key": "text_custom_field",
                    ...
                }
            }
        }
    }
}

As you can see, there are just small differences.

Let me know what you think 🙂

SantosGuillamot commented 7 months ago

Can we please include documentation in the planning for the RC?

Sure, I just did! Thanks for pointing that out 🙂

eric-michel commented 7 months ago

A new update with the things that were included in the last Gutenberg release and will be available for testing after the RC...

This looks amazing! I love that various block attributes (other than just content) are already supported! It's truly amazing to me how fast y'all are able to implement this.

One UI suggestion I can provide from the perspective of someone supporting users: instead of having certain controls simply disappear for attributes that are connected to custom fields (like the "Replace" button for changing an image), have them visually disabled with a tooltip that explains to the user why they cannot change that attribute. I think that will be clearer to our users what's going on.

Even better would be to make that tooltip customizable so that, as the site developer creating these connections, I can provide very brief instructions on where they can go to actually edit that value.

SantosGuillamot commented 7 months ago

Thanks a lot for the feedback! 🙂 Everything you said makes sense to me and I believe it's worth exploring that possibility. I don't know how feasible it is in terms of code right now, maybe it requires bigger changes like this issue, but something to take into account for sure.

SantosGuillamot commented 7 months ago

Update

Since this other update, there has been some work focused on the list of tasks needed for Gutenberg 17.6.

Done

Next

Nice to have It'd be great to have this list ready for beta, but I'd prioritize the rest of the issues.

gziolo commented 7 months ago

The WordPress 6.5 Beta 1 is scheduled for February 13th (Tuesday). I want to raise the point that we need to make two important decisions that aren't listed in the short term plan.

Add a WP_Block_Binding_Source class and handle validation there: https://github.com/WordPress/gutenberg/pull/58337#discussion_r1469227481.

It’s going to be very difficult to refactor it in WordPress core after Beta 1. We need to decide if WP_Block_Bindings_Source is necessary or if we can continue with an array. At the moment, there isn't much logic we could abstract. This is what we have:

https://github.com/WordPress/wordpress-develop/blob/8d47e6497180221ad2e180e65bedce5ba4f4b2f8/src/wp-includes/class-wp-block.php#L273-L275

$source_callback = $block_binding_source['get_value_callback'];
$source_args       = ! empty( $block_binding['args'] ) && is_array( $block_binding['args'] ) ? $block_binding['args'] : array();
$source_value     = call_user_func_array( $source_callback, array( $source_args, $this, $attribute_name ) );

That could become:

$source_args   = ! empty( $block_binding['args'] ) && is_array( $block_binding['args'] ) ? $block_binding['args'] : array();
$source_value = $block_binding_source->get_value( $source_args, $this, $attribute_name );

Aside: we need to add the logic that ensures that get_value_callback is defined when registering the source.

Refactoring the processing of block bindings into two steps: https://github.com/WordPress/wordpress-develop/pull/5888#discussion_r1462922587. This would solve an issue with the empty images in pattern overrides.

I believe it’s an even more important decision, and it has been raised several times, including this issue from @draganescu. I’m in favor of applying this refactoring before Tuesday next week.

SantosGuillamot commented 7 months ago

Thanks for sharing! It totally makes sense to me 🙂 I'll update the comment and the opening post to reflect that.

talldan commented 7 months ago

I believe it’s an even more important decision, and it has been raised several times, including https://github.com/WordPress/gutenberg/issues/58510 from @draganescu. I’m in favor of applying this refactoring before Tuesday next week.

Is it the same as this issue - Pattern Overrides: Image block doesn't render on frontend when it's saved as a placeholder in a pattern?

gziolo commented 7 months ago

I believe it’s an even more important decision, and it has been raised several times, including #58510 from @draganescu. I’m in favor of applying this refactoring before Tuesday next week.

Is it the same as this issue - Pattern Overrides: Image block doesn't render on frontend when it's saved as a placeholder in a pattern?

Yes, that's related. I don't think it will fully resolve the issue with the Image block in the placeholder state, but it definitely will help to render something on the frontend.

SantosGuillamot commented 6 months ago

WordPress 6.5 update

Now that WordPress 6.5 feature freeze is here, I wanted to make an update on what is expected to be part of 6.5 and which other important functionalities are left for future releases.

We might still fix/improve some things during the beta phase. You can take a look at the opening post for detailed updates.

Included in 6.5

Two different functionalities are coming in 6.5:

1. Possibility to connect block attributes and custom fields

WordPress 6.5 is expected to include the very first version of this functionality to connect block attributes and custom fields. Users will be able to bind them by adding a "bindings" object in the block attributes:

<!-- wp:paragraph {"metadata":{"bindings":{"content":{"source":"core/post-meta","args":{"key":"my_custom_field"}}}}} -->
<p>Paragraph</p>
<!-- /wp:paragraph -->

Just by adding that, it will work both in the editor and the frontend:

It is important to remember that, in this initial version, only a few block attributes can be connected with all types of registered sources:

This demo shared in a previous comment showcases what will be possible in 6.5:

https://github.com/WordPress/gutenberg/assets/34552881/ed62013e-692c-45c8-849c-3a1a74f4224f

2. External developers/plugins can add support for other dynamic data sources

The underlying code used to connect custom fields, the Block Bindings API, has been designed to be extensible enough so it is easier to connect block bindings and other dynamic data sources. This release includes a basic public API allowing developers/plugins to register their own sources.

In the same way Gutenberg is registering the post meta source, anyone could register their custom source myplugin/plugin-data:

register_block_bindings_source(
    'myplugin/plugin-data',
    array(
        'label'              => _x( 'Plugin Data', 'block bindings source' ),
    'get_value_callback' => 'my_plugin_block_bindings_plugin_data_callback',
    )
);

And in the callback, instead of calling get_post_meta function, it could call any relevant function like get_my_plugin_data.

Just by doing that, users could connect block attributes and the new source in the same way they connect them to custom fields:

<!-- wp:paragraph {"metadata":{"bindings":{"content":{"source":"myplugin/plugin-data","args":{"key":"plugin_key"}}}}} -->
<p>Paragraph</p>
<!-- /wp:paragraph -->

Future releases

As already mention, this is just an initial version that will already help users, but there are more things we should work on after that. These are some of the next steps I personally consider more relevant:

fabiankaegy commented 6 months ago

Thanks for this update ❤️

Am I correct in understanding that even for the custom data sources that developers can add they can only be used for the mentioned supported block attributes?

Paragraph: content. Heading: content. Image: URL, alt, and title. Button: text, URL, linkTarget, rel.

SantosGuillamot commented 6 months ago

Am I correct in understanding that even for the custom data sources that developers can add they can only be used for the mentioned supported block attributes?

Yes, that's correct. It was decided to keep a smaller set of blocks to ensure everything work as expected. The idea is to expand the support gradually using the HTML API.

If there are any block attributes users consider more important, we could look at those first.

gziolo commented 6 months ago

I updated the previous https://github.com/WordPress/gutenberg/issues/53300#issuecomment-1938463648 to make it clearer that the list of supported attributes applies to all registered sources:

- It is important to remember that, in this initial version, only a few block attributes can be connected:
+ It is important to remember that, in this initial version, only a few block attributes can be connected with all types of registered sources: 
fabiankaegy commented 6 months ago

Now that we are past the Beta 1 cut off point I'm removing this tracking issue from the 6.5 Project board. From now on the board should only contain individual bugs that we want to still fix before 6.5 gets released.

dinhtungdu commented 6 months ago

Be able to edit the value of the custom fields when a binding exists: The functionality has been coded with this in mind, but it wasn't included in this initial version to ensure it works as expected.

@SantosGuillamot do we have any issue/discussion for this one specifically? I can't find one in the repo.

If we haven't already, I'd strongly recommend that we include the updating behavior of the custom field in Site Editor > Pages. For now, we can edit only the title and content of the page. But if we can also edit the custom field value there, it'd be a truly WYSIWYG editing experience. Btw, editors working on content only won't have to worry about breaking the template.

Also, in the future, if we support not only pages but other post types to be edited in the Site Editor, we can have live-editing experiences for any type of content on the site, like products or events.

I'm super excited for the future of editing with Custom fields and Blocking Binding API. Thank everyone involved for the amazing work!

fabiankaegy commented 6 months ago

@dinhtungdu in order to have other blocks besides the featured image, title, and content editable we need to solve https://github.com/WordPress/gutenberg/issues/59290

SantosGuillamot commented 6 months ago

@SantosGuillamot do we have any issue/discussion for this one specifically? I can't find one in the repo.

I opened this experiment to explore how it could work, and it was also explored in this refactoring.

I am confident that it is feasible, and it worked nicely in the testing. It is something I'd definitely like to explore deeper. However, I believe it was premature to include that possibility in WordPress 6.5. There are still some uncertainties we need to clarify before adding that functionality, and it seemed better to wait to ensure that whatever lands work as expected and it is backward compatible.

SantosGuillamot commented 5 months ago

Update - Changes made during WordPress 6.5 beta phase

Now that the beta phase has finished and we can only expect to fix critical bugs, it's time to make a summary of the most important issues addressed during this period.

Apart from that, some resources to understand better the custom fields and bindings were created:


From here, I'll wrap up WordPress 6.5 in the opening comment and I'll transform this issue into an epic issue to track the upcoming releases for both the custom fields project and the block bindings API. They are highly related and it seems it is easier to follow if the discussions happen in the same place.

Additionally, I plan to post another comment with ideas for WordPress 6.6 and update the opening comment as well.

SantosGuillamot commented 5 months ago

Potential plan for WordPress 6.6

Now that WordPress 6.5 is almost out, it's time to start planning for 6.6.

It is important to keep in mind that this is a short release. WordPress 6.6 Beta 1 estimated date is the 4th of June. And I believe we should aim to have things ready two weeks before to test it properly in Gutenberg. That leaves us a couple of months.

For that reason, I'd like to keep the scope tight and work on other things progressively if there is enough bandwidth in the end.

Having said that, these are the issues I would consider more important:

I believe that, if this is shipped in WordPress 6.6, it'd be a great iteration over the existing functionalities.

From there, if we feel confident and there's still time, we can work on other aspects like the following ones. But I'd consider them out of the scope for now:

Having said that, any feedback is more than welcome. And it's important to note that the planning might change based on that 🙂

As usual, we'll try to keep the opening comment updated with the progress and we'll publish updates in this thread.

lgladdy commented 5 months ago

@SantosGuillamot I feel like the UI to add bindings is probably more important than things like updating the values.

Right now, there's a risk of third party plugins creating their own binding UI and we end up with loads of different variations per binding source plugin.

I'd rather spend time contributing towards that goal in core than try to ship something sooner in ACF. It's also the one question we've had most on our team with our experimental binding support plugin. It was also the first question on the wptavern article on bindings where someone asking how to create their own UI for adding a binding.

ndiego commented 5 months ago

Right now, there's a risk of third party plugins creating their own binding UI and we end up with loads of different variations per binding source plugin.

I agree with this, and it's the first thing I thought about building 😅 Creating a standardized UI that plugin developers can extend is very important.

SantosGuillamot commented 5 months ago

Thanks a lot for your feedback :slightly_smiling_face:

I agree having a UI to create bindings that can be extended by plugin developers is really important. And you made really good points. Let me share some of the reasons why I considered working on the editing part first:

Having said that, we should probably start exploring how it could look like and how it could be implemented, but I’m not sure if it’s feasible to have it for 6.6. I’m just trying to be realistic given the resources we’ve had till now for this project. I’m more than happy to start those conversations, try to clarify the uncertainties, and push that forward.

gziolo commented 5 months ago

I feel like the UI to add bindings is probably more important than things like updating the values.

Right now, there's a risk of third party plugins creating their own binding UI and we end up with loads of different variations per binding source plugin.

Thank you for your feedback on that one. There are some prototypes, so it might be a good idea to spend some time creating an experiment in the Gutenberg plugin to gather feedback about one of the approaches considered so far.

These three items on the list are related. In fact, I commented on #58233, resharing the items linking to my comments on PRs. I think it would be helpful to group them together, example:

Having these changes in place would make it easier to open Block Bindings to new core blocks.

annezazu commented 5 months ago

Hey folks! For 6.6, can you all create a new epic issue outlining what's being thought of and close this issue out? This will help us see the progression of a feature scoped for each release over time and help ensure any discussion in the comments is relevant to the current release.

SantosGuillamot commented 4 months ago

Hey folks! For 6.6, can you all create a new epic issue outlining what's being thought of and close this issue out?

As suggested here, and after discussing it with @priethor , I'm closing this issue as an iteration for WP 6.5. I've opened two new issues: