Make WordPress Core

Opened 5 years ago

Closed 5 years ago

Last modified 5 years ago

#45250 closed defect (bug) (wontfix)

Block editor scripts should be enqueued in an action hooked to `admin_enqueue_scripts` as done in Gutenberg

Reported by: chouby's profile Chouby Owned by:
Milestone: Priority: normal
Severity: normal Version: 5.0
Component: Editor Keywords: has-patch
Focuses: Cc:

Description

An important feature that Polylang provides to the users is to prefill the new translations with information coming from the original post. Every type of content can be prefilled: post fields, taxonomies and post metas.

In WordPress 5.0-beta2-43852, the editor does not read informations filled int the global $post ( for post fields) or in the database ( for taxonomies and metas) for a new post.

This issue had been reported during the development of Gutenberg in https://github.com/WordPress/gutenberg/issues/7000 and was partially fixed by https://github.com/WordPress/gutenberg/pull/10660 and https://github.com/WordPress/gutenberg/pull/10362
but in WordPress 5.0, nothing works anymore.

Here is a small plugin demonstrating the issue (you may need to change the thumbnail id for the test).

<?php

/*
Plugin name: Test Post Prefill
*/

add_action( 'add_meta_boxes', function( $post_type, $post ) {
	if ( 'post-new.php' == $GLOBALS['pagenow'] ) {
		$post->post_title     = 'Test post prefill';
		$post->post_content   = 'Test post content prefill';
		$post->menu_order     = 10;
		$post->comment_status = 'open';
		$post->ping_status    = 'closed';

		wp_set_post_categories( $post->ID, 1 );
		wp_set_post_tags( $post->ID, 'tag' );

		set_post_thumbnail( $post->ID, 42 );

		stick_post( $post->ID );
	}
}, 10, 2 );

I'll also attach a picture with the test results.

Attachments (2)

post-prefill-test-results.png (27.3 KB) - added by Chouby 5 years ago.
Test results with WP 4.9.8, Gutenberg and WP 5.0
45250.patch (20.9 KB) - added by Chouby 5 years ago.
enqueue editor scrips in a function hooked to admin_enque_scripts

Download all attachments as: .zip

Change History (13)

@Chouby
5 years ago

Test results with WP 4.9.8, Gutenberg and WP 5.0

#1 @danielbachhuber
5 years ago

  • Keywords needs-patch added
  • Milestone changed from Awaiting Review to 5.0

#2 @danielbachhuber
5 years ago

  • Keywords reporter-feedback added; needs-patch removed

@Chouby In looking at this a bit further, I don't think the code snippet you've provided is the "correct" way to overload the default post.

WordPress formally supports the default_content, default_excerpt, and default_title filters. I've verified these work as expected with the block editor on the 5.0 branch.

The code snippet you've included worked through happenstance pre-5.0. For the other values, I think you'll need to filter rest_prepare_post, rest_prepare_page, etc. to include the default values.

add_filter( 'rest_prepare_page', function( $response, $post ){
	if ( 'auto-draft' === $post->post_status ) {
		$response->data['menu_order'] = 2;
	}
	return $response;
}, 10, 2 );

#3 @Chouby
5 years ago

@danielbachhuber Thank you for looking in to this. I also made some progress in my investigations. The difference of behavior betweeen Gutenberg and WP 5.0 is due to the order in which things are done:

  • In Gutenberg, the action add_meta_boxes is fired before the editor scripts are added because the function gutenberg_editor_scripts_and_styles() which adds scripts is correctly hooked to admin_enqueue_scripts and https://github.com/WordPress/gutenberg/pull/10660 restored the order between the 2 actions. This is, I believe, the behavior that we should expect.
  • In WP 5.0, the action add_meta_boxes is fired after the editor scripts are added because the scripts are added directly in the file edit-form-blocks.php without enqueuing them in a function hooked to admin_enqueue_scripts. This is, I believe, not the correct way to add scripts.

Regarding fields not working, even in Gutenberg, such as menu_order, I had envisaged to use the rest_prepare_{$post_type} filter when I tried to solve the issue with Gutenberg https://github.com/WordPress/gutenberg/pull/7421#issuecomment-399432232 but at that time, there was a blocking issue with the post title.

Now, filtering the REST response would work for the fields such as menu_order as you tested it, but it would not work for the title, content and excerpt. That means that Gutenberg/WP 5.0 introduces some inconsistent behavior. Some fields need to be filtered in the REST response and some other using the global $post variable (or the filters default_content, default_excerpt and default_title which in fact have always and are still just an indirect way to modify only 3 properties of the global variable).

Is there a way to know if the REST request is coming from the blocks editor and not from anywhere outside?

Last edited 5 years ago by Chouby (previous) (diff)

#4 @danielbachhuber
5 years ago

Now, filtering the REST response would work for the fields such as menu_order as you tested it, but it would not work for the title, content and excerpt. That means that Gutenberg/WP 5.0 introduces some inconsistent behavior. Some fields need to be filtered in the REST response and some other using the global $post variable (or the filters default_content, default_excerpt and default_title which in fact have always and are still just an indirect way to modify only 3 properties of the global variable).

Ugh.

Is there a way to know if the REST request is coming from the blocks editor and not from anywhere outside?

Not in precise manner, no. $pagenow is likely the best indicator you have.

@Chouby
5 years ago

enqueue editor scrips in a function hooked to admin_enque_scripts

#5 @Chouby
5 years ago

  • Keywords has-patch added; reporter-feedback removed

45250.patch proposes to enqueue the block editor scripts in a function hooked to admin_enqueue_scripts as it is in Gutenberg and as I suppose we should do.

#6 @danielbachhuber
5 years ago

I don't have a strong opinion about this. @pento ?

#7 @Chouby
5 years ago

I see now that edit-form-advanced.php is also enqueuing scripts outside the admin_enqueue_scripts action. I never paid attention to that.

To understand my issue to make Polylang work correctly with WP 5.0, you should know that I often hook to the action add_meta_boxes to do various things such as prefilling the content, create new content (taxonomy terms, media), remove the editor for the translations of the posts page, or manage compatibility with some plugins. I understand that all these things were not the pimary goal of the action add_meta_boxes but with the classic editor, add_meta_boxes is the first non-deprecated action after the current $post_ID is known and before anything is loaded in the editor.

With the current status of WP 5.0, the action add_meta_boxes is fired after the content is preloaded via the REST API which breaks all the features I hooked to this action. So I propose 2 alternatives to the proposed patch.

  1. Move the call to register_and_do_post_meta_boxes( $post ); at the beginning of edit-form-advanced.php still to restore the current behavior of WP < 5.0 (even with Gutenberg) where the action is fired before the content is loaded.
  1. Add a new action after the $post_ID is known and before the content is loaded. Ideally this new action should be avalaible in the 2 editors for new and edited posts.

What do you think?

NB: I just created a related issue #45263 as the block editor now allows to edit the posts page which is not the case with the classic editor. It's related because I currently use the add_meta_boxes action to reproduce the same behavior for the translations of the posts page.

#8 @pento
5 years ago

  • Keywords reporter-feedback added

@Chouby: Are you able to hook into the wp_insert_post_data filter, and modify the post data when the post_status is set to auto-draft?

It seems like that should work in both the classic and block editor to change the default data.

#9 @Chouby
5 years ago

  • Keywords reporter-feedback removed
  • Summary changed from Backward compatibility: Impossible to prefill a new post in WP 5.0 to Block editor scripts should be enqueued in an action hooked to `admin_enqueue_scripts` as done in Gutenberg

@pento Thank you for the suggestion. I am not sure to remember but it's possible that I never used this filter because the first data that I prefilled were custom fields, long before $meta_input was added to $postarr. But your suggestion may be a very good solution to unify my code for both editors. For sure, I will look at it.

For now I already have a working workaround, using the suggestion from @danielbachhuber and the action rest_api_init to replace add_metaboxes when using the block editor.

However, I did not close the ticket because I still believe that the difference of behavior between WP 4.9.8 + Gutenberg on one side and WP 5.0 on the other side is disturbing, although I am not sure if someone else than me would be disturbed. That's why I proposed the patch to enqueue the scripts in a function hooked to admin_enqueue_scripts as done in Gutenberg.

I am changing the title to reflect this.

#10 @pento
5 years ago

  • Milestone 5.0 deleted
  • Resolution set to wontfix
  • Status changed from new to closed

Thank you for the feedback, @Chouby.

I'm going to leave the behaviour as is, there are a myriad of ways that meta boxes have been registered over the years, and it's not really possible to replicate all of these in the block editor. The block editor's meta box support is provide to help transition to the new interface, but will ultimately need to be phased out.

I would recommend sticking with your workaround for now, but ultimately looking at how to integrate with the new APIs provided by the block editor.

#11 @Chouby
5 years ago

@pento, I am not sure that we understood each other. The issue is not at all related to metaboxes.

It appears that in Polylang, I am using the action add_meta_boxes for other features than adding the metabox and that's how I noticed the issue reported here.

The issue is about a different behavior between the plugin Gutenberg (installed on top of WP 4.9.8) on one side and WP 5.0 on the other side. In Gutenberg, the action is fired before the scripts are enqueued. In WP 5.0, the action is fired after the scripts are enqueued.

My understanding of the project is that, since most of the development and tests have been done in Gutenberg, WP 5.0 should behave exactly as WP 4.9.8 + Gutenberg. But maybe I am wrong on this assumption?

The purpose of the ticket and patch was to restore the same behavior in WP 5.0 as in Gutenberg.

I am thoroughly testing the development versions of WP 5.0 so I noticed the issue and found a workaround so I won't insist more than that. However, this may impact other 3rd party devs. I can't know for sure.

Note: See TracTickets for help on using tickets.