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

Fix metabox reordering #30617

Merged
merged 22 commits into from
Aug 30, 2021
Merged

Conversation

ribaricplusplus
Copy link
Member

@ribaricplusplus ribaricplusplus commented Apr 8, 2021

Description

Fixes #30071

Important: This PR also includes changes to WordPress core. I will submit those here: https://core.trac.wordpress.org/ticket/52818

Cause of issue:

postboxes.js wp-admin script (this one), which is responsible for saving meta box order, is initialized by setAvailableMetaBoxesPerLocation here:

if ( window.postboxes.page !== postType ) {
window.postboxes.add_postbox_toggles( postType );
}

However, that function is called from post.php, here:

https://github.com/WordPress/WordPress/blob/57da3e781320dd62e3016624b310c23447d9e6d1/wp-admin/includes/post.php#L2379-L2381

But at that point the editor is not yet fully initialized because setupEditor action didn't run yet. So postType is still null, postboxes becomes initialized incorrectly (with null instead of proper post type), and then when reordering happens the reordered metaboxes are saved incorrectly.

How has this been tested?

Manually. Try changing metabox order. Steps to reproduce are given in the linked issue.

Types of changes

Bug fix

Checklist:

  • My code is tested.
  • My code follows the WordPress code style.
  • My code follows the accessibility standards.
  • I've tested my changes with keyboard and screen readers.
  • My code has proper inline documentation.
  • I've included developer documentation if appropriate.

I'm not sure if anything needs to be changed for React Native:

  • I've updated all React Native files affected by any refactorings/renamings in this PR (please manually search all *.native.js files for terms that need renaming or removal).

@ribaricplusplus ribaricplusplus marked this pull request as ready for review April 8, 2021 15:44
@ribaricplusplus ribaricplusplus added [Feature] Meta Boxes A draggable box shown on the post editing screen [Type] Bug An existing feature does not function as intended labels Apr 8, 2021
Copy link
Contributor

@peterwilsoncc peterwilsoncc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed this fixes the bug with some manual testing. Also checked the postType is passed as a string on trunk with some well placed console.logs and that is the case too.

@@ -102,6 +106,7 @@ function Editor( {
? getEditedPostTemplate()
: null,
post: postObject,
isEditorReady: __unstableIsEditorReady(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reading the coding standards and wondering if this should be returned with the __unstable prefix too.

What am I missing? This is mainly for my own education rather than an opinion either way :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was following the style established elsewhere in the code where __unstable and __experimental is often removed, for example here:

import {
BlockBreadcrumb,
__experimentalLibrary as Library,
} from '@wordpress/block-editor';
import { Button, ScrollLock, Popover } from '@wordpress/components';
import {
useViewportMatch,
__experimentalUseDialog as useDialog,
} from '@wordpress/compose';

Also, if I'm not mistaken, it seems that the __unstable and __experimental prefix is there for people using Gutenberg packages in their projects, so it's important not to document these functions and tell people to use them and so forth. Here it's just used locally and not exported anywhere.

That's just my reasoning for renaming it, but I'll put the __unstable prefix back if you think that would be better.

@paaljoachim
Copy link
Contributor

I believe this PR could use some additional eyes...
@mcsf @ockham @youknowriad

@youknowriad
Copy link
Contributor

Hi there! thanks for the fix here, it seems to me that the current way this call is handled could be improved, and this is highlighted by the issue being fixed here.

In other words and to avoid any timing issues in the future, what about a solution like this:

1- Remove the promise from here https://github.com/WordPress/WordPress/blob/57da3e781320dd62e3016624b310c23447d9e6d1/wp-admin/includes/post.php#L2379-L2381 and just call setAvailableMetaBoxesPerLocation action synchronously.

2- Split the setAvailableMetaBoxesPerLocation action creator to two separate action steps:
a- one that sets the state in the store (saves the active meta boxes)
b- one that triggers the post box script and also enables the meta boxes saving: all this code

const postType = yield controls.select(
'core/editor',
'getCurrentPostType'
);
if ( window.postboxes.page !== postType ) {
window.postboxes.add_postbox_toggles( postType );
}
let wasSavingPost = yield controls.select( 'core/editor', 'isSavingPost' );
let wasAutosavingPost = yield controls.select(
'core/editor',
'isAutosavingPost'
);
// Meta boxes are initialized once at page load. It is not necessary to
// account for updates on each state change.
//
// See: https://github.com/WordPress/WordPress/blob/5.1.1/wp-admin/includes/post.php#L2307-L2309
const hasActiveMetaBoxes = yield controls.select(
editPostStore.name,
'hasMetaBoxes'
);
// First remove any existing subscription in order to prevent multiple saves
if ( !! saveMetaboxUnsubscribe ) {
saveMetaboxUnsubscribe();
}
// Save metaboxes when performing a full save on the post.
saveMetaboxUnsubscribe = subscribe( () => {
const isSavingPost = select( 'core/editor' ).isSavingPost();
const isAutosavingPost = select( 'core/editor' ).isAutosavingPost();
// Save metaboxes on save completion, except for autosaves that are not a post preview.
const shouldTriggerMetaboxesSave =
hasActiveMetaBoxes &&
wasSavingPost &&
! isSavingPost &&
! wasAutosavingPost;
// Save current state for next inspection.
wasSavingPost = isSavingPost;
wasAutosavingPost = isAutosavingPost;
if ( shouldTriggerMetaboxesSave ) {
dispatch( editPostStore.name ).requestMetaBoxUpdates();
}
} );

c- when setting the metaboxes, only call the second part if the editor is ready

3- Add an effect somewhere in the MetaBoxes component that monitors __unstableIsEditorReady and calls the action defined in b above when the flag is set to true.

The main reason I'm suggesting this is to make the code less dependent on the timing of the actions being called. Does that sound like a better solution?

@paaljoachim
Copy link
Contributor

Associated PR:
Allow moving metaboxes to previously empty area
#25187

@ribaricplusplus
Copy link
Member Author

ribaricplusplus commented May 11, 2021

Thank you for the review @youknowriad.

Your suggestions sound good. However, I realized that I will not be able to invest time into this PR for at least a month. Just wanted to let you know. If it's still relevant when I can invest time in it, I'll do it.

@desrosj
Copy link
Contributor

desrosj commented Jul 28, 2021

Hey @ribaricplusplus, just wanted to see if you had some time that freed up to revise this PR. I'd love to wrap this one up and get it shipped in a 5.8.x release of WordPress.

@rodrigo-arias
Copy link

Hi, I'm having a similar issue with ACF that I think has the same origin. After inserting a taxonomy I cannot open the meta boxes. The error doesn't happen in WP 5.6.x

CleanShot 2021-07-28 at 16 53 17

I've seen a similar report here: https://core.trac.wordpress.org/ticket/52818

CleanShot 2021-07-28 at 16 34 56@2x

It would be great if you could have this fix for the next minor version as right now it is hard to use the block editor since WP 5.7 with this bug.

Thank you

@ribaricplusplus
Copy link
Member Author

I haven't forgotten about this, but finding time is a struggle!

I'll update you in the next few days about when I'll be able to work on this.

@ribaricplusplus
Copy link
Member Author

I'll try to do it mid September.

@ribaricplusplus
Copy link
Member Author

ribaricplusplus commented Aug 27, 2021

@youknowriad Hey. I've made the changes as you proposed, the patch to WordPress core is here: https://core.trac.wordpress.org/ticket/52818

Please review this again and let me know if something still needs to be changed.

Copy link
Contributor

@youknowriad youknowriad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking very good to me, I'd appreciate some testing from folks relying on meta boxes a bit.

I assume this works even without the Core patch right (as we're supposed to support existing and previous WP versions in the Gutenberg plugin)

@ribaricplusplus
Copy link
Member Author

ribaricplusplus commented Aug 29, 2021

I assume this works even without the Core patch right

@youknowriad Yes.

I'd appreciate some testing from folks relying on meta boxes a bit.

@desrosj Can you mention anyone who could potentially do some testing?

@ribaricplusplus
Copy link
Member Author

ribaricplusplus commented Aug 29, 2021

@youknowriad I just realized that my previous solution was actually not good because the MetaBoxes component is created multiple times for different values of the location parameter. So the effect that initializes meta boxes would also run multiple times.

Now I extracted the meta box initializing logic into a separate action on the edit-post store.

@paaljoachim paaljoachim added the Backport to WP Minor Release Pull request that needs to be backported to a WordPress minor release label Aug 29, 2021
*
* @return {boolean} Whether meta boxes are initialized.
*/
export function metaBoxesInitialized( state ) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we maybe rename this one areMetaBoxesInitialized, hasInitializedMetaboxes or something like that to match the naming scheme of the other selectors?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Contributor

@youknowriad youknowriad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still looking good. Good point on the extraction to an action + isInitialized check.

@youknowriad
Copy link
Contributor

Thanks for your work and persistence here :)

@youknowriad youknowriad merged commit 893b2b8 into WordPress:trunk Aug 30, 2021
@github-actions github-actions bot added this to the Gutenberg 11.5 milestone Aug 30, 2021
@ribaricplusplus ribaricplusplus deleted the fix/metabox-order branch August 30, 2021 11:14
desrosj pushed a commit that referenced this pull request Aug 30, 2021
@desrosj desrosj mentioned this pull request Aug 30, 2021
7 tasks
@dariaknl
Copy link

dariaknl commented Sep 1, 2021

Tested on a last checkout from trunk: the re-ordering bug from the original issue is not reproduced. Re-ordering is kept after updating the post.

desrosj added a commit that referenced this pull request Sep 1, 2021
* Fix API docs generation (#33384)

* Docs: use markdown headings instead of links for API declarations (#33381)

* Docs: Run Prettier after updating API in documentation (#33498)

(cherry picked from commit 626f233)

* Use tabs instead of spaces in block transform doc example (#33549)

(cherry picked from commit 8afca1e)

* Fix metabox reordering (#30617).

* Block editor: don't render layout and duotone styles in between blocks (#32083)

* Widgets: Allow HTML tags in description (#33814)

* Widgets: Allow HTML tags in description

* Use `dangerouslySetInnerHTML`

Avoid `<div />` inside the `<p />` tag

* Describe by dangerouslySetInnerHTML is used

* Use safeHTML

* Update comment

* Editor: Set 'hide_empty' for the most used terms query (#33457)

Don't include terms that aren't assigned to any posts as "most used" terms.

* Update widget editor help links to point to the new support article (#33482)

* If select-all fires in .editor-post-title__input, end the process.. (#33621)

* Writing flow: select all: remove early return for post title (#33699)

* Call onChangeSectionExpanded conditionally (#33618)

* FontSizePicker: Use number values when the initial value is a number (#33679)

* FontSizePicker: Don't use units if the value is a number
* Add unit tests
* Disable units when we have number values

* Fix justification for button block when selected (#33739)

* Remove margin setting, auto right conflict with justify buttons

* Per review, add little margin back

* Add error boundaries to widget screens (#33771)

* Add error boundary to edit widgets screen

* Add error boundary to customize widgets

* Refactor sidebar controls provider to application level so that its state is not lost when re-initializing

* Revert "Refactor sidebar controls provider to application level so that its state is not lost when re-initializing"

This reverts commit 7d607ff.

* Remove rebootability from customize widgets

* Remove debug code

* Fix insertion point in Widgets editors (#33802)

* Default batch processor: Respect the batch endpoint's maxItems (#34280)

This updates the default batch processor to make multiple batch requests
if the number of requests to process exceeds the number of requests that
the batch endpoint can handle.

We determine the number of requests that the batch endpoint can handle
by making a preflight OPTIONS request to /batch/v1. By default it is 25
requests.

See https://make.wordpress.org/core/2020/11/20/rest-api-batch-framework-in-wordpress-5-6/.

* Fix button block focus trap after a URL has been added (#34314)

* Rework button block link UI to match RichText format implementation

* Refine some more, determine visibility by selection and url state

* Add e2e test

* Also focus rich text when unlinking using a keyboard shortcut

* Text for dropdown fields within legacy widgets in the Customizer is off centered (#34076)

* Fix ESLint errors reported

* Regenerate autogenerated docs

* Update the `INSERTER_SEARCH_SELECTOR` path.

This is a partial cherry pick of 2356b2d in order to fix the performance tests.

Co-authored-by: André <nosolosw@users.noreply.github.com>
Co-authored-by: JuanMa <juanma.garrido@gmail.com>
Co-authored-by: Greg Ziółkowski <grzegorz@gziolo.pl>
Co-authored-by: Jeff Bowen <jblz@users.noreply.github.com>
Co-authored-by: Bruno Ribarić <43731400+ribaricplusplus@users.noreply.github.com>
Co-authored-by: Ella van Durpe <4710635+ellatrix@users.noreply.github.com>
Co-authored-by: Petter Walbø Johnsgård <petter@dekode.no>
Co-authored-by: George Mamadashvili <georgemamadashvili@gmail.com>
Co-authored-by: Daniel Richards <daniel.richards@automattic.com>
Co-authored-by: Hiroshi Urabe <mail@torounit.com>
Co-authored-by: Kai Hao <kevin830726@gmail.com>
Co-authored-by: Marcus Kazmierczak <marcus@mkaz.com>
Co-authored-by: Robert Anderson <robert@noisysocks.com>
Co-authored-by: Anton Vlasenko <43744263+anton-vlasenko@users.noreply.github.com>
@Mamaduka Mamaduka removed the Backport to WP Minor Release Pull request that needs to be backported to a WordPress minor release label Jan 12, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Meta Boxes A draggable box shown on the post editing screen [Type] Bug An existing feature does not function as intended
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Meta box reordering does not save in user preferences
8 participants