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

Custom fields connected to Blocks #51373

Open
mtias opened this issue Jun 9, 2023 · 28 comments
Open

Custom fields connected to Blocks #51373

mtias opened this issue Jun 9, 2023 · 28 comments
Assignees
Labels
[Feature] Block API API that allows to express the block paradigm. [Type] Overview Comprehensive, high level view of an area of focus often with multiple tracking issues

Comments

@mtias
Copy link
Member

mtias commented Jun 9, 2023


At WCEU contributor day I brought up an idea to a few people on how we could connect blocks and custom fields in a compelling way. In the early days, we had explored a "meta" block attribute source that allowed block authors to create blocks consuming data from post meta. It worked alright but the behavior predated some of the latest block API affordances — like entity handling — and had the limitation of being accessible only for block developers. The other limitation was that we didn't have enough knowledge of how the final html output should render to recreate it on the server, so the PHP output was handled ad hoc on the blocks that consumed fields. This new approach can overcome both obstacles.

The way it'd work is by connecting attributes from normal static blocks (content on paragraph, url on image, and so on) to meta keys instead of serializing their content. So far so good. The crucial difference is that it doesn't require a new custom block with a custom attribute but leverages the built-in blocks as the primary interface. This means we can work out a UI in the block inspector that just needs to handle the connection but doesn't need to support editing nor extrinsic validation because the block itself takes care of it through its normal setAttribute flow. For example, updating a meta key for an image url would be as easy as dragging an image into the connected image block for a user. This also means patterns would just work out of the box transparently — a user can insert a pattern they like and map the heading block content to a field, the image source to another field, and so on. The edit UI for updating content remains the same.

To overcome the need to rebuild the html on the server we can employ the source declaration as a tag delimiter if we pair it with the new tag processor.

"content": {
	"type": "string",
	"source": "html",
	"selector": "p",
	"default": "",
	"__experimentalRole": "content"
},

The gist of it is that the way a block declares how to query a serialized source can also function as an indication of how to reassemble that attribute properly. The implementation can thus reutilize an existing API contract instead of introducing a new syntax for tokens. (See #39831.)

Proposal

  • The selector functions as a token placement, so we don't need additional syntax. The tag processor can find the element and we reconstruct innerHtml entirely as it's just a simple composition of <$selector>$field</$selector>. This means we don't need the full block recipe from save because we are just replacing specific attributes.
  • Since we are just dealing with block attributes, block variations can be created on demand for convenience.
  • Transforming between blocks can retain the connection as long as they are valid transforms (so a paragraph using "book author" meta can be turned into a heading using "book author" meta).
  • Users should be able to create and assign fields on the fly through the inspector UI, which right now is blocked by the show_in_rest requirement (only meta fields registered with show in rest would be available to pick from).
  • We can probably reduce the amount of specific blocks needed (post title, etc) down the road as we have discussed previously, as long as variations can have namespace aliases.
  • This mechanic can help us simplify the various approaches to The wp:pattern block #48458 as it bypàsses the need for additional syntax.
@mtias mtias added [Feature] Block API API that allows to express the block paradigm. [Type] Overview Comprehensive, high level view of an area of focus often with multiple tracking issues labels Jun 9, 2023
@mtias mtias changed the title Custom Field 🔗 Blocks Custom fields 🔗 Blocks Jun 9, 2023
@youknowriad youknowriad self-assigned this Jun 9, 2023
@joshuatf
Copy link
Contributor

@mtias Love this proposal! Would the above also work for blocks that are form elements?

The new product editor being worked on in Woo is form-based but composed via blocks, I'm wondering if the <$selector>$field</$selector> approach would work for an element like a checkbox or any data type that is not strictly presentational.

This could be a misunderstanding on my part of how this API is intended to work, so please correct me if I'm misunderstanding how it's meant to be used.

@mtias mtias mentioned this issue Jun 29, 2023
58 tasks
@tkapler
Copy link

tkapler commented Jul 10, 2023

In my opinion:

  1. "custom field" should NOT be a block, but more something like [shortcode] - so an inline field, that you could put to any text element - either Paragraph, header etc. - as a part of it, not as a whole element.
  2. And this should not by only custom field, but it should be possible to definite it programmatically - e.g. I am currently using shortcode [total], that displays total number of posts, or I can e.g. create combine the value of multiple fields, e.g. cost and currency and create [price] that would should price with currency.
  3. it should be possible to put this element in the text or in e.g. link URL or image src, or even use it in some layout input field - e.g. width of some element, optimally there should be some filter, whare i could easily limit, in what fields my custom field will be available
  4. and it would be great if in any such field would have some way, how can i select from available fields (so e.g. menu in the editor, similar to current selection of e.g. footnote, subscript etc.)
  5. it would be great if it would be possible to display the value differently than it is stored (so .e.g. i could display time as HH:MM:SS, but internally it would be stored as miliseconds, or to display 1234 as 1.234,00.
  6. again it would be great, if i would have some way, how to switch the displaed format - e.g. simple dropdown on that value. And there should be again some filter, with which i can define what formats will be recommended to me or even define my own one
  7. i can easily switch somewhere in editor either to display values or codes
  8. i can add the shortcode in both templates and posts content. Optimaly even in e.g. post titles (can be done programatically)

How i imagine it?

IMO the easiest way would redefinition of shortcodes or implementing e.g. "curly brackets shortcode".

So you can put anywhere [my-custom-field-name] (or {my-custom-field-name} and it would replace it with the the value of my-custom-field-name meta or value of that "shortcode" defined programatically

or I can put there [my-custom-field-name format:hhmmss] and it would use format hhmmss that is defined somewhere (some default list of format will be provided)

And in Gutenberg, it would look like some highlighted
image

@mtias
Copy link
Member Author

mtias commented Jul 12, 2023

@tkapler that's a different enterprise than this issue encapsulates, you can see the ongoing discussions about inline dynamic tokens in #39831

@gregoirenoyelle
Copy link

Hi @youknowriad
I use more and more this plugin and it works quite well.
https://wordpress.org/plugins/display-a-meta-field-as-block/
You should have a look.
It’s very useful when you need to make some advanced FSE templates. And you can use ACF meta.

@tresorama
Copy link

tresorama commented Jul 31, 2023

Elementor Dynamic Data

I like the UX of how Elementor Pro let you use "Custom Field".
Here is a demo the UX https://www.youtube.com/watch?v=OWUbJrRq7jI

Considerations

1
I think that the Elementor way is applicable only to "dynamic block" ( Gutenberg Blocks that are saved to DB inside "post_content" as JSON data and ALWAYS rendered to HTML on page request phase, as opposed to "static block" that are saved in DB as HTML after being rendered in React side as HTML in the creation phase ) due to their dynamic nature.

2
While custom fields with "string" data type are easy to handle, some other custom field types are instead difficult and it's impossible to anticipate real usage.
I'm thinking of "ACF Repeater", or "ACF Gallery".
These complex fields are usually saved as JSON objects (that can include array inside it).

3
Using a custom field inside the Block Editor require 2 distinctive phases.

  1. Data Value Extraction, which handles getting data value from DB.
  2. Data Rendering, that is consuming the value with Gutenberg Block

Raw Idea

Single data type
Meaning "string", "number" data type, that can be cast to string and rendered easily.
The Gutenberg Block let the user get the data with a new Button "Dynamic Data" placed in the Block Toolbar, which on click shows a dropdown of custom field names.
An input lets the user also define a nested path in case it's needed, in a JS dot notion fashion (object.property.subProperty).

Multiple data
In the case of an array of things, something similar to the Query Loop is required.
So a new ForEach Gutenberg Block can be used to extract/read the array from the custom field, and then "innerBlocks" of the "ForEach" are treated as the item template, which is repeated for every item of the array.
"ForEach" block provides extracted data with React Context (or similar) to its children.
Children block of "ForEach" use the same strategy to get custom field data as described in Single data type, with the difference that new values are available thanks to "ForEach" extraction.

An alternative name for the "ForEach" block could be "CustomFieldLoop" to resemble the "QueryLoop" one.


Meanwhile the Meta Field Plugin mentioned by @gregoirenoyelle is the "best at the moment" for what I found...

@mtias
Copy link
Member Author

mtias commented Aug 3, 2023

@tresorama with the original proposal it'd work for any block type, including static blocks that serialize as html.

@tresorama
Copy link

@tresorama with the original proposal it'd work for any block type, including static blocks that serialize as html.

So the user, after changing the custom field value must manually re-save the post content where it's used?

@mtias
Copy link
Member Author

mtias commented Aug 3, 2023

No, it's a dynamic value, only the first save (when you connect the block to the field) is necessary.

@tresorama
Copy link

Great, so it's saved only where the value comes from and where it needs to be shown.
Now I see how it can be used also with static blocks.

@carlomanf
Copy link

carlomanf commented Aug 3, 2023

Is #41073 in scope? If so, should I close it as a duplicate?

Edit: It seems the idea I expressed in that issue covers the case of inner blocks, as opposed to an attribute value.

@tresorama
Copy link

tresorama commented Aug 7, 2023

This is how Bricks Builder lets you inject Dynamic Data into various "places".

Bricks make no distinction between Custom Fields (post_meta) and other post type property like "post_content" or "featured_image".
They are only "Dynamic Data".

Dynamic data is an API that let get data from database, from various sources.
Bricks supports major Custom Fields Plugin , like ACF, Pods, Toolset and others.

Here is a demo of the UX.

https://youtu.be/w4Bv-Pd6n2w?si=pCPMHCwI3sr74E4h

It would be great to build something similar, that can be used by many Gutenberg Block.
This would cover Custom Fields and also all the core Wordpress data coming from post types.

@cr0ybot
Copy link
Contributor

cr0ybot commented Aug 8, 2023

This would be a huge win for agencies doing custom theme work utilizing the site editor. It would be much simpler to design block templates that output custom field values via core blocks. I wonder, though, if it would be possible to not limit this to just post meta, but expose some API or block context that could control values by some other means.

For instance, I am working on a plugin that outputs blocks that happen to be headings and images and text. These are custom blocks so that they can grab a value via block context and display it. However, I would prefer to use core blocks, simply overriding the content (text, image URL, etc) with a value provided by a parent block or otherwise controlled.

@SantosGuillamot
Copy link
Contributor

not limit this to just post meta...
...
use core blocks, simply overriding the content (text, image URL, etc) with a value provided by a parent block or otherwise controlled

I agree this could be a great improvement and should be explored. Actually, in this initial tracking issue to experiment with the custom fields I mentioned something similar.

Basically, the end goal would be to connect block attributes to values that could be obtained from different sources.

The first supported source will probably be the meta/custom fields. But we should explore other sources like another block context as suggested.

@mtias
Copy link
Member Author

mtias commented Aug 9, 2023

Yeah, post meta is just one of the main surface areas to include first, since it also has the registration side to sort out, but there are other post properties we'd want to also include.

@draganescu
Copy link
Contributor

I am so glad we're exploring the route of dynamic attributes and reserve tokens for inline dynamic content.

I wonder if the notion of dynamic attributes could be separated from the custom fields limitation, and have custom fields as one potential source. We could bind anything - including data outside wordpress - via custom callbacks. That may be farther down the road, but definitely worth considering.

@gziolo
Copy link
Member

gziolo commented Aug 31, 2023

I wonder if the notion of dynamic attributes could be separated from the custom fields limitation, and have custom fields as one potential source. We could bind anything - including data outside wordpress - via custom callbacks. That may be farther down the road, but definitely worth considering.

We are aiming to build a general-purpose solution that through a single API added for blocks can support custom fields, post meta, site settings, user settings, and basically everything plugins can create.

@masteradhoc
Copy link
Contributor

a big +1 from our side. Our Agency would benefit a lot from this!

@cr0ybot
Copy link
Contributor

cr0ybot commented Sep 13, 2023

Without any context for the data type of the value (as mentioned by @tresorama) this solution could be very limited and possibly have a bunch of unwanted side-effects.

For instance, would you really want to select from any post meta field when assigning a URL value for a button block? Ideally, I'd only want to see insertable fields that are expected to be valid URLs.

I wonder if the Fields API project could be mutually beneficial here, since the goal there is not just to register post meta/site/settings fields with a unified API, but also to define the shape of the data. If each block allowing the use of "dynamic attributes" could also set what field types are valid for insertion, I think it would result in a smoother user experience. It would also allow for more advanced data types to be handled, like arrays with a specified schema.

I'd also like to see a way to hook into the valid data type configuration for specific dynamic block attributes as a way for plugins to extend blocks to support custom data types.

@SantosGuillamot
Copy link
Contributor

I suggested a plan to include an initial version of this in WordPress 6.5: link. We'll use that issue to share progress. As shared there, I believe we can start small and add new functionalities progressively. Please feel free to leave any feedback 🙂

@courtneyr-dev
Copy link
Contributor

@mtias I was speaking with @sc0ttkclark about this and the wording for the Beta 1 release post. As this is a bit different than the Core Fields API project, I'm concerned about confusion around the wording here. Could you please review it?

@sc0ttkclark
Copy link

sc0ttkclark commented Feb 2, 2024

What if we called this something like "Dynamic Data API for Custom Fields" or "Dynamic Data Connections API for Custom Fields"?

As this isn't really a Custom Fields API for the block editor itself, it may cause confusion around other future efforts as we try to build more functionality with the block editor for those types of things.

@afercia afercia changed the title Custom fields 🔗 Blocks Custom fields connected to Blocks Feb 5, 2024
@afercia
Copy link
Contributor

afercia commented Feb 5, 2024

Coming here from #54536 where I noticed an emoji as part of this isue title:

Screenshot 2024-02-05 at 15 11 38

While emojis are cute and funny, please let's avoid to use them in place of meaningful text. They are okay to use when the emoji name as provided by the operating system provides a correct meaning in tht specific context. They are misleading and not inclusive when their name makes a sentence unclear because the emoji is used only with a 'visual' purpose. Github issues should be accessible to everyone.

An issue title that reads Custom fields link symbol Blocks isn't great.

@mtias
Copy link
Member Author

mtias commented Feb 7, 2024

@courtneyr-dev @sc0ttkclark sure! Open to using "Dynamic Data" as the designator, but it's not dynamic data for custom fields, it's dynamic data for block attributes. The primary source for the dynamic data are meta fields, hence the original scope of the issue, but it can be any other entity (like options, or other post meta that is not custom fields, like featured image).

@unscripted
Copy link
Member

First off, I want to acknowledge that naming things is difficult. So, thank you to everyone for putting these options out there.

I originally was team "Custom Fields API," which is currently used in the 6.5 highlight grid (#58028). However, what @mtias mentioned about the other entities makes me wonder if "Custom Fields" may be too limiting.

The primary source for the dynamic data are meta fields, hence the original scope of the issue, but it can be any other entity (like options, or other post meta that is not custom fields, like featured image)

I wanted to see if a current definition for "Dynamic Content" is being used anywhere in an official manner. I checked the glossary, and the only dynamic item defined is "Dynamic Blocks."

The reason I ask is when working through this type of functionality over the last year, the industry seems to have gravitated to calling this functionality "Dynamic Content." I can definitely understand if we want to differentiate from the third-party builder world of WP, but I could also see the benefit of using a term that seems to have already been adopted.

Based on my understanding of the efforts underway and from various searches, my recommendation would be "Dynamic Content API."

Below are two screenshots of Google's suggested searches when typing "WordPress dynamic" and "Gutenberg dynamic."

A screenshot of Google suggestions for the search term: WordPress dynamic. A screenshot of Google suggestions for the search term: Gutenberg dynamic.

@sc0ttkclark
Copy link

Dynamic Content API is exactly what this is, and it fits with the normalization of that concept in many page builders and block plugins.

@gziolo
Copy link
Member

gziolo commented Apr 25, 2024

The majority of the work has been accomplished and shipped in WordPress 6.5. There are now new tracking and epic issues that contain all the details outlining the remaining work:

A more detailed explanation of where we are concerning the original proposal:

The selector functions as a token placement, so we don't need additional syntax. The tag processor can find the element and we reconstruct innerHtml entirely as it's just a simple composition of <$selector>$field</$selector>. This means we don't need the full block recipe from save because we are just replacing specific attributes.

It's exactly how it is implemented for the Paragraph, Heading, Button, and Image blocks. We expect to open it to all blocks in the far future where HTML API is capable of querying block attributes sourced from HTML and replacing inner HTML.

Since we are just dealing with block attributes, block variations can be created on demand for convenience.

This is now possible and we see that extenders started leveraging block variations to expose the core blocks connected to custom sources in the inserter.

Transforming between blocks can retain the connection as long as they are valid transforms (so a paragraph using "book author" meta can be turned into a heading using "book author" meta).

This is implemented for core blocks that support block bindings.

Users should be able to create and assign fields on the fly through the inspector UI, which right now is blocked by the show_in_rest requirement (only meta fields registered with show in rest would be available to pick from).

In the initial implementation, only post meta is supported in WordPress core and individual fields need to have show_in_rest set to true so it would get replaced with the value on the server. However, extenders are free to do whatever they want in that regard. There is now UI for connecting attributes and custom fields but it's tentatively planned for WordPress 6.7.

We can probably reduce the amount of specific blocks needed (post title, etc) down the road as we have discussed previously, as long as variations can have namespace aliases.

That one depends on:

This mechanic can help us simplify the various approaches to #48458 as it bypàsses the need for additional syntax.

Patter Overrides are being tracked in:

Given all of the above. I think we can close this overview issue. Matias, feel free to reopen if you think it would be still valuable to keep it open for some time.

@gziolo gziolo closed this as completed Apr 25, 2024
@fabiankaegy
Copy link
Member

Hey @gziolo 👋

As I understand it in an effort to keep GitHub more organized / easier to navigate the idea was to have high level Overview issues (like this one) that stay open for the entire lifetime of a feature. These issues are meant to be the "North Star" for the UX / general direction of the feature.

Then there are Tracking / Epic / Iteration issues which are the ones you link to that are specific to WordPress core release cycles etc.

You can find more insights about this in Slack here: https://wordpress.slack.com/archives/C02QB2JS7/p1711046533012709

Because of that my vore would be to not close this Overview Issue and instead update its contents to that it can allow people coming to this to find the current actionalbe elements for this feature.

This will make it much easier to find / reference all the related work

@gziolo
Copy link
Member

gziolo commented Apr 25, 2024

There is a top-level overview issue for Block API where all the mentioned issues are listed:

There is a tracking issue for Block Bindings:

It has the latest details related to the next steps for advancing connecting custom fields to blocks. We can keep this overview issue open if that helps to make things more organized.

@gziolo gziolo reopened this Apr 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Block API API that allows to express the block paradigm. [Type] Overview Comprehensive, high level view of an area of focus often with multiple tracking issues
Projects
None yet
Development

No branches or pull requests