Skip to content

Custom fields connected to Blocks #51373

Open
@mtias

Description

@mtias
Member

Note

This is an integral part of the block API #41236


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.

Activity

added
[Feature] Block APIAPI that allows to express the block paradigm.
[Type] OverviewComprehensive, high level view of an area of focus often with multiple tracking issues
on Jun 9, 2023
changed the title [-]Custom Field 🔗 Blocks[/-] [+]Custom fields 🔗 Blocks[/+] on Jun 9, 2023
self-assigned this
on Jun 9, 2023
joshuatf

joshuatf commented on Jun 21, 2023

@joshuatf
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.

tkapler

tkapler commented on Jul 10, 2023

@tkapler

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

mtias commented on Jul 12, 2023

@mtias
MemberAuthor

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

gregoirenoyelle

gregoirenoyelle commented on Jul 24, 2023

@gregoirenoyelle

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

tresorama commented on Jul 31, 2023

@tresorama

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

mtias commented on Aug 3, 2023

@mtias
MemberAuthor

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

tresorama

tresorama commented on Aug 3, 2023

@tresorama

@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

mtias commented on Aug 3, 2023

@mtias
MemberAuthor

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

33 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

[Feature] Block APIAPI that allows to express the block paradigm.[Type] OverviewComprehensive, high level view of an area of focus often with multiple tracking issues

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Development

    No branches or pull requests

      Participants

      @draganescu@youknowriad@cr0ybot@mtias@gziolo

      Issue actions

        Custom fields connected to Blocks · Issue #51373 · WordPress/gutenberg