WordPress / gutenberg

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

Block meta attributes and Custom Fields panel conflict #23078

Open nk-o opened 4 years ago

nk-o commented 4 years ago

Describe the bug We have a block with an attribute, which saves in post meta. This block is working with no problem. Then we activate the Custom Fields panel and now changed in block attribute value will not be saved in post meta.

To reproduce Steps to reproduce the behavior:

  1. Create a block with meta attribute - https://developer.wordpress.org/block-editor/tutorials/metabox/meta-block-3-add/

  2. Don't forget to register meta field in PHP - https://developer.wordpress.org/block-editor/tutorials/metabox/meta-block-2-register-meta/

  3. Insert this block in the post, fill the text control and update the post image

  4. Make sure your meta value saved in post (reload the page and you will see this value in field)

  5. Activate Custom Fields panel image

  6. Try to change the block value, then update the post and reload the page

  7. You will see, that your new meta value was not saved

Expected behavior Custom meta should be synchronized automatically when editing block attributes and editing Custom Fields panel.

Editor version:

Desktop:

Additional context

talldan commented 3 years ago

A different issue, but the same problem was discussed in a slack triage session: https://wordpress.slack.com/archives/C02QB2JS7/p1625549733336200

I think the problem happens because there are two API requests happening in the background. One REST request to update the post, and that's followed by an ajax request to post.php to update metaboxes. My hunch is that the second request overwrites the values set by the first.

I can think of two potential fixes:

Probably other options too.

bobbingwide commented 3 years ago

I think the problem happens because there are two API requests happening in the background.

I came to the same conclusion trying to develop a generic post meta field block. https://github.com/bobbingwide/sb-field-block/issues/2#issuecomment-871393212

Notes:

I can think of two potential fixes:

Are these fixes something that would be implemented by core or would each block have to do it? If the latter, what mechanisms are available?

talldan commented 3 years ago

Are these fixes something that would be implemented by core or would each block have to do it?

I'm thinking this would be in the Gutenberg codebase. This is where metabox saving happens: https://github.com/WordPress/gutenberg/blob/1f55df53a0ec469c7abd7cbdb65568b08d84f906/packages/edit-post/src/store/actions.js#L335-L398

So that might be a place to investigate.

kraftner commented 2 years ago

EDIT: Please have a look at https://github.com/WordPress/gutenberg/issues/23078#issuecomment-1111220849 for a much better workaround.


Since this can cause major issues and breakage I was looking for a workaround.

I didn't see any other solution than the nuclear option to completely disable the Custom Fields panel.

Please ensure you know what you are doing here before proceeding since

⚠️💀 Completely disabling the Custom Fields panel 💀⚠️

There are actually two parts to it:

Force-Disabling the Custom Fields panel

Since the preference whether to show the Custom Fields panel is stored in user meta we can just force it to always be false.

add_filter('get_user_metadata', function($value, $object_id, $meta_key, $single, $meta_type){
    if($meta_key !== 'enable_custom_fields'){
        return $value;
    }
    return false;
}, 10, 5);

Removing the setting in the preferences panel

You can still see the toggle to enable the Custom Fields panel in the preferences panel though. But it doesn't have any effect any more which is very bad/confusing UX. So:

Due to this check

https://github.com/WordPress/gutenberg/blob/b8aa52dc4a1fe3887be27d5f3d1a77b409dc8750/packages/edit-post/src/components/preferences-modal/meta-boxes-section.js#L58

we can hide the setting like this:

add_filter('block_editor_settings_all', function ($editorSettings, $editorContext) ){
    unset($editorSettings['enableCustomFields']);
    return $editorSettings;
}, 10, 2);
kraftner commented 2 years ago

Okay, scrap that, it is actually way easier. Just remove the meta box which also hides the settings panel. You can even do it just for those post types you want. Way better than what I had in https://github.com/WordPress/gutenberg/issues/23078#issuecomment-1111194202. 🤣

add_action('add_meta_boxes', function( $post_type, $post ){
    if ($post_type !== 'my-custom-post-type') {
        return;
    }
    remove_meta_box(
        'postcustom',
        null,
        'normal'
    );
},10, 2);
gin0115 commented 1 year ago

I found you can either prepend your meta key with an _ to denote it as a private key, or use the is_protected_meta to mark your keys as private (again) and also excluded from the custom field panel/meta box.

Rilele commented 9 months ago

I found you can either prepend your meta key with an _ to denote it as a private key, or use the is_protected_meta to mark your keys as private (again) and also excluded from the custom field panel/meta box.

I tried this an I got an error that I'm not allowed to edit the field. Did I miss something?

lipemat commented 6 months ago

I found you can either prepend your meta key with an _ to denote it as a private key, or use the is_protected_meta to mark your keys as private (again) and also excluded from the custom field panel/meta box.

I tried this an I got an error that I'm not allowed to edit the field. Did I miss something?

Turns out you also need to add 'auth_callback' => '__return_true' when you register the meta or register_meta will set $args['auth_callback'] = '__return_false'.

SantosGuillamot commented 4 weeks ago

I have started this pull request trying to solve this issue. Although I must say that I am not familiar with that code and I am not sure if that's a viable approach.