Block Bindings in WordPress 7.0
Supersedes #67520.
Enhancements
- [ ] Filter available source items for a given attribute by format.
- See this preliminary exploration and discussion.
- We'll do this in close collaboration with @oandregal, who's approaching formats for the Fields API. See the tracking issue and this example.
- [ ] https://github.com/WordPress/gutenberg/issues/64870
- Related exploration: https://github.com/WordPress/gutenberg/pull/72391
- Take two: https://github.com/WordPress/gutenberg/pull/73889
Explorations
- [ ] Bind multiple attributes to a single source. Example: Bind Image block's
url,alt,titleattributes to post's featured image (exposed viacore/post-datasource).- Related exploration: https://github.com/WordPress/gutenberg/pull/71002
- [ ] Try binding a block that requires a "repeater" concept. Example: Bind Gallery block to list of images.
- [ ] Streamline the API based on recurring usage patterns in
getValuesandgetFieldsList.- Examples include passing more arguments to them (e.g. block name, attributes); or providing additional ways for a block source to communicate that it will not expose and source items for a given block, attribute, or other context. (Things that are currently done by e.g. returning
[]fromgetFieldsList, based on certain criteria.)
- Examples include passing more arguments to them (e.g. block name, attributes); or providing additional ways for a block source to communicate that it will not expose and source items for a given block, attribute, or other context. (Things that are currently done by e.g. returning
- [ ] https://github.com/WordPress/gutenberg/issues/73461
- [ ] Remove requirement to define a block bindings source both on the server and client side. Instead, allow server-side only definition, and communicate to the client. See this comment, bullet point 4, for a suggestion how to do this.
- [ ] https://github.com/WordPress/gutenberg/issues/73423
Code Quality
- [x] https://github.com/WordPress/gutenberg/pull/73366
- [x] https://github.com/WordPress/gutenberg/pull/73579
- [ ] https://github.com/WordPress/gutenberg/pull/72096
Adding another request shared by @getdave in Slack:
Missing entities has been a problem in the Nav block. For 6.9 I had to implement our own
getEntityRecordscalls to determine when a link was in a broken state. Ideally this should be information we can get from the Block Binding itself.We’d need to know
- is the entity missing
- the post status of the entity (this might be taking it too far but for Nav this is a legit problem)
- whether the entity resolution has happened - no point in showing error states if the entity is still resolving
Edit: Possibly(?) related: https://github.com/WordPress/gutenberg/pull/66962
We may need to add some more blocks to the compatibility list. Like "Cover". And include it in pattern overrides.
We'll do this in close collaboration with @oandregal, who's approaching formats for the Fields API. See the https://github.com/WordPress/gutenberg/issues/73154 and https://github.com/WordPress/gutenberg/pull/72999.
@ockham We've landed support for (display) formats in the Field API. In talking to @youknowriad we don't think we need to migrate the Field API to follow the JSON Schema, however, the blocks may want to align with the Field API. They way we are experimenting with generating UI controls for content-only blocks may be relevant for block bindings.
Should we add a way to determine if a source is compatible per block or per block attribute level?
Well, the format could be the way to go: https://github.com/WordPress/gutenberg/issues/72446
Having just tested Block Bindings in 6.9 and working on a diagram of the current support I will share some feedback:
- Some concern about permissions being baked into the get values functions. What if we have a headless solution and are using JWT or oAuth and want to bake the blocks and pass the output? This seems to force us to simulate a user in order to pass the user_can_do_stuff() checks, otherwise the core functions will always produce null. They will also seemingly fail silently having just returned null without any logging of the failed value retrieval.
- core/post-data has only 3 pieces of data (link, date, modified) returned from _block_bindings_post_data_get_value(). Seeing as the function is already there and it takes only 2-3 lines per piece of data, why wouldn't we return everything available from the standard field set (title, status, author) etc? Is there some blockage around what format(s) to support, because I can foresee some complication around how to handle something like author, or even status where there is "published" and "Published". Return formats and handling might be an issue, it would seem like the goal for most users would be to display the label for a status (Published).
- On the topic of "formats" which I think might be discussed in respect to fields API separately, it seems important to have flexibility in what is returned particularly from core data sources because if the flexibility is lacking, 3rd parties will have no choice but to roll their own (often duplicated) solutions when they could instead be focused on writing more useful support for a wider range of data. I'd suggest having an extendable abstract class like \Core\Data\Format and \Core\Data\FormatRegistry so that each data source could define/register data formats using a shared approach that would be discoverable with a function like block_bindings_source_formats('core/post-data', 'status'), that would return array of "key", "label", "array" (published, Published, [key=published, label=Published].
- It seems like in order to fully support the UI selection we have to duplicate the data return in JS, and thus have to try to align our PHP return function with our JS return function, creating some maintenance challenges and also some adoption and documentation challenges. Can we not think of a way to power the JS from the PHP? The data ultimately is all coming from the DB/PHP so why would we be handling the same data for the same purpose in JS? Why not auto-register an endpoint for each data source and in
registerBlockBindingsSource()make getValues optional. If omitted, a REST request fetches the data automatically from the PHP source (by calling the auto-route created by PHP). Allowing devs to provide a getValues() still has utility if they really need to do something different in the editor side, but for 95% of use cases where the goal (made difficult by cross-language implementation) is to return the exact same data in the same format - eliminating the duplication would makes thing much more stable and improve documentation/adoption. The auto-routes for example would be something like /wp/v2/bindings/source/core/post-data and this returns all the discovery information, which fields, what formats etc. - In 6.9 tests of the UI for binding, I found only custom data sources are available in the UI? Is that the expected usage? I was expecting to see the core/post-meta and core/post-data, but instead saw only my custom data source available.
- It seems as if many of the filters/functions involved in block bindings only work in the Gutenberg editor. Is it the case that some of the files (PHP) involved are not loaded outside of Gutenberg? I'm not sure on whether this is the case, but when I tried out various functions and filters that I found many of them just didn't run on the front or even in the admin, and I only saw them run when opening Gutenberg. Some of the filters might be useful for discovery (to build UI's outside Gutenberg), for example you can imagine there are a lot of use cases around checking what data sources are available on a site-wide basis perhaps to power a dashboard widget or to prepare an export from a plugin.
- Regarding AI support for Block Bindings... there isn't any. Claude Sonnet 4.5 and other leading models have nearly 0% accuracy for block bindings. Most seem to believe the block markup format is bindings.[attribute], skipping the metadata wrapper... then they get the data sources wrong and that's even the ones that existed prior to 6.9, all advice about UI, use of PHP or JS registration... at least AI is consistent in providing 100% incorrect information on this topic. But this is a problem, and it is made worse that even models that are good at reading docs find a range of outdated docs and thus will continue to produce errors even after a deep think with research. The solution is partly having a singular authoritative set of documentation so that we can direct models to read it and discard everything else they have from training on the topic. The challenge isn't just that models need the new/accurate info, they need to be made aware that this is an evolving API and that most/all of their prior data is just wrong. Perhaps a condensed version of docs for Block Bindings could be made specifically for AI models.
- I have made a diagram of the core supports. Feel free to use/share if you find it useful and if you have ideas or samples you think would help to expand it out to a larger "cheatsheet reference" let me know.
Hey @caseyjmilne, thank you for your feedback! This is one of the most thorough reviews of Block Bindings I've seen for WP 6.9, and I really appreciate it! Find my replies to your bullet points below.
- (This one I’ll have to think about some more.)
- Yeah, we ran out of time to extend
core/post-datain time for 6.9. You’re spot-on that the problem was largely related to formats; aside from the examples you gave, this also affects the title (which is typically available inrenderedandrawformats from the REST API endpoint, depending on permissions). Another big one is the featured image, which raised the question if we might need a syntax to bind multiple attributes (e.g. an Image block’surl,alt,titleetc) to one given data source item. We have an early-stage exploration for the latter here. - For formats, my preference would be to align as much as possible with existing standards. (We’ve been actively discussing this here; we haven’t agreed on a solution yet, but it looks like we’re either going with the Fields API convention, or with the JSON Schema standard). I think that in this case, too much extensibility can actually be a downside; we don’t want multiple source providers to define a different name for a fairly universal concept such as a date or URL. Instead, those formats should align with block attributes.
- Yes, this is a very good point. The duplication of code between PHP and JS (and the necessity to sort of define a block bindings source twice) has also irked me. Removing this in favor of solely PHP-defined sources is something we could try exploring during the WP 7.0 cycle. I’ll add a tentative bullet point to the tracking issue.
- The
core/post-datesource is indeed limited to a few block types only for now, butcore/post-metashould be available more widely. If you have post meta defined for a given post type, it should show up in the block inspector’s editor panel. I wonder if you’re seeing an instance of this issue maybe? - This one I’m not sure I’m following 100%. Could you elaborate which block bindings related filters and functions specifically?
- I’ll talk to documentation folks about this. Edit: Looks like they're already on it!
- Thank you, that looks very useful! Maybe our docs folks can use those diagrams.
@ockham thanks, regarding core/post-meta I was able to see the UI for it in later tests. I can't recall exactly which filters it was (on point 6) but I believe it was the one for discovering the support attributes per block. I'll take note of it again if I see a situation where a filter doesn't run outside Gutenberg.