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

UI/UX for connecting block attributes to custom fields #53891

Open
michalczaplinski opened this issue Aug 23, 2023 · 8 comments
Open

UI/UX for connecting block attributes to custom fields #53891

michalczaplinski opened this issue Aug 23, 2023 · 8 comments
Labels
[Feature] Block bindings [Feature] Custom Fields Anything related to the custom fields project - connecting block attributes and dynamic values Needs Design Needs design efforts. [Type] Enhancement A suggestion for improvement.

Comments

@michalczaplinski
Copy link
Contributor

Work has started to implement the vision outlined in Custom fields 🔗 Blocks. and is being tracked in #53300.

However, we need a more holistic vision of the UI/UX for the connections between the blocks' attributes and the custom fields. This issue aims to explore the possible UI/UX for those connections.

Current State

2 PRs have been merged that allow connecting the Paragraph block's content attribute to custom fields:

Another (draft) PR is exploring connecting the Image block's url and title attributes to custom fields:

This is what connecting the attributes looks like at the moment for both Image and Paragraph blocks (includes the changes from the unmerged PR):

original.mov

This UX is not optimal and needs refinement.

Open Questions

Those are roughly in the order of importance:

How to edit the custom fields?

  • Inside of the block content, like in Add custom attributes sources block support #51375

    • How will the users know if they are editing the value of a custom field or the content? There should be some visual indicator around the block to distinguish between editing the block content and the value of the custom field.
  • Using an external editor? (like using ACF or the built-in custom fields GB panel). This is what the built-in custom fields panel looks like:

    Screenshot 2023-08-23 at 11 23 34
  • Using a different approach for each block.
    Maybe a single UI does not make sense for all blocks, and we need to design it in a way that makes sense for each block individually.

    • For Paragraph block, which only connects the content attribute to custom fields, it might make sense to edit the value in the block content.
    • For Image block, we could have something like:
      • to connect the url attribute you can select the custom field after inserting the block:
        Screenshot 2023-08-23 at 12 07 32
      • to connect the title or other attributes, there might be inspector controls (like it works currently)

UI for connecting more than one attribute of a block to custom sources.

Currently, only the Image block has more than 1 connection, but this will change in the future. Having an input field per "connectable" attribute (as in the current MVP) is not tenable.

How to show the list of available fields? (ideally with autocomplete)

There is prior art for this:

UI for adding a new custom field inline

It should be possible to create new custom fields on the fly using the same UI where the attributes get connected to custom fields.

Interaction between existing block content and the connection value in the editor

If a block has existing content and then gets connected to a custom field, what should happen to this existing content? Ideally, we'd like to keep it in the background somehow, and if a user removes the connection, show that content again. Currently, we remove the existing content in the Paragraph block and show a placeholder. What should this process look like for other blocks and attributes?

Selecting a specific value from a custom field that is an array or object

Custom fields can be more than strings and numbers. We need some way to select/filter those.

If the connection has a default value, how should this be shown to the user?

We want the connections to define a "default" value that should be used in case the custom field we're connecting to does not exist. It should be indicated to the user that the "default" value is being used instead of the value from the connection.

UI for selecting a “connection source” (meta fields or something else)

This is not a priority because, for now, the only "connection source" is "custom fields", but there will be others in the future like "parent block" or another external source.

Validation

This one is probably optional for now, but ACF and similar plugins allow users to define validation rules for each field.

@michalczaplinski michalczaplinski added Needs Design Needs design efforts. [Feature] Custom Fields Anything related to the custom fields project - connecting block attributes and dynamic values labels Aug 23, 2023
@tresorama
Copy link

This is a POC i made for myself some days ago of I would like this feature to be implemented...
My vision about dynamic data is that they can be presented in any point of the conent (for fields of type text, number, or any other that can be casted to text).

POC - The UX

Kapture.2023-08-23.at.22.04.17.mp4
@jordesign jordesign added the [Type] Enhancement A suggestion for improvement. label Aug 24, 2023
@michalczaplinski
Copy link
Contributor Author

CC @WordPress/gutenberg-design

@michalczaplinski
Copy link
Contributor Author

Nice @tresorama! Are you using #42015 in your POC? It seems more related to the discussion around inline tokens (#39831) than the current issue.

How would you imagine your proposal working beyond plain text content, e.g., with Images/media?

@tresorama
Copy link

Thanks. I'm not using #42015 because i didn't know it exists :) I used a mini parser with the same idea to replace tokens with real value coming from the redux store.
The dropdown in the toolbar is used only to copy and paste the token in the "attributes.content" string.
Here i've shown the "edit" side only, but the an identical parser is needed in PHP side that will "preg_replace" the block content when rendered on frontend.

I haven't moved on over "textual" data because of time, but i think that for example "core/image" block can have an additional source in the initial modal (and also in "replace" popover)
Schermata 2023-08-25 alle 09 47 42

Or maybe move every source inside the same dropdown (link in Bricks, shown below) ??


Bricks UX with Dynamic Data

My vision is heavily influenced by Bricks Builder, so i'd like to see in Core Gutenberg a UX flow similar to Bricks.

Bricks can be tested freely in a playground going to https://try.bricksbuilder.io/ if anyone want to test it.
You need to sign up an account (free) and then a Wordpress instance is spawn up for you, with ACF, Woocommerce, and other common plugin already installed (but deactivated).

Here is a recording of using Bricks with Dynamic Data

Kapture.2023-08-25.at.09.22.43.mp4

Considerations:

Bricks show every possible Dynamic Data source in every dynamic data dropdown, even if :

  • the current Block supports only a particular "type" (text, image...)
  • the current post type (global post type of the page or current item in a query loop) does not have that "field" as an available option

For the first,
Bricks check If type is wrong after user selection, and in case the type is wrong it fails silently (as in the video below).
It is good to remember that Bricks is targeted to Developer only, which will know why it happens.
Gutenberg IMO is targeted in between Common User and Developer, so maybe a UI for when type is wrong is a good addition, but not essential in early phase of the feature.

Here is an example of a type mismatch in Bricks

Kapture.2023-08-25.at.09.42.00.mp4

For the second,
ACF doesn't store fields as post_meta ( but they have planned to migrating to post_meta in near future ) and this can cause some "overexposing" field like in Bricks.
In my POC I get field used to populate the toolbar dropdown with this code

const useDynamicDataSources = (props: BlockEditProps<any>) => {
  const { attributes, context } = props;

  // extract dynamic data fields "names" and return as list

  // fetch data
  const post = useEntityRecord<Post>('postType', context.postType, context.postId);
  const acfFields = post.record.acf || {};

  // build list
  return [
    { section_name: 'Post', fields: ['post_title'].map(_ => "{" + _ + "}") },
    { section_name: 'ACF', fields: Object.keys(acfFields).map(_ => "{acf:" + _ + "}") },
  ] satisfies { section_name: string, fields: Array<string>; }[];

};

In case here is the full code of my POC


@tresorama
Copy link

Builder that solved the same problem that can be used as inspiration in this design phase are:

  • Bricks
  • Elementor Pro
  • Breakdance
  • Kadence
  • GenerateBlocks
  • any other ???

@michalczaplinski maybe you could add these in the main issue to have them togheter

@bvlgn
Copy link

bvlgn commented Aug 31, 2023

The user should edit the custom fields (or other data sources) either inside the block content (or related popup) or in a block inspector panel. Not in an external editor!
 
I don’t think the user needs to know that they technically are adding content to a custom filed or other data source. But they should know what they are expected to enter. So when connecting attributes to a data source it is important we can add a placeholder and a label which would show when the input field in the block editor gets focus. This label could be shown in the toolbar for the block. 



Instead of trying to connect attributes to data sources from within the block’s UI we should offer an ‘Attributes’ panel. In this panel we make connections, add placeholders, labels, add input instructions, set defaults, set the attribute to be read only or read-write and allow creation of new data source fields.  Here we could also define options the user may select from and set any other configuration needs. This panel should by default only be available to administrators, I think.

When switching an attributes data source the current value should preferably be moved to the new data source. If the new data source already has a value then the user should choose which value to keep.
 
If the connection has a default value it should be filled in by default. The user can then overwrite it or leave it as is. If there is no default value a placeholder should be shown.
 
When it comes to validation and filtering maybe an API could be added and let the implementation to extenders? That said, a robust and complete API should be considered from the get go.



So values are mainly edited in the editor or a block inspector panel while attribute connections are configured in the Attributes block inspector panel.

@gziolo
Copy link
Member

gziolo commented Apr 23, 2024

@michalczaplinski and @SantosGuillamot, is this issue still actionable? There are other issues opened that seem to cover similar topics.

@michalczaplinski
Copy link
Contributor Author

@gziolo There isn't anything directly actionable, but we can keep this issue open for now and once work on the UI/UX picks up we can link from here and/or close this issue.

Quick summary:

Connecting block attributes to custom fields is one of the main aspects of the Block Bindings project. It was shipped in WP 6.5 (#53300). Current work is tracked in:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Block bindings [Feature] Custom Fields Anything related to the custom fields project - connecting block attributes and dynamic values Needs Design Needs design efforts. [Type] Enhancement A suggestion for improvement.
6 participants