Skip to content

Administration: Support custom post statuses in the Publish meta box. - #14834

Open
Sabbir345 wants to merge 2 commits into
WordPress:trunkfrom
Sabbir345:fix/12706-custom-post-status-publish-box
Open

Sabbir345 wants to merge 2 commits into
WordPress:trunkfrom
Sabbir345:fix/12706-custom-post-status-publish-box

Conversation

@Sabbir345

Copy link
Copy Markdown

Trac ticket: https://core.trac.wordpress.org/ticket/12706

The classic editor's Publish meta box only renders options for the built-in post statuses. When editing a post that has a registered custom status (for example in-review), the "Status:" label is empty and the status dropdown has no matching option. The browser then submits the first option, so clicking "Save Draft" silently changes the post's status to pending:

register_post_status( 'in-review', array( 'label' => 'In Review', 'protected' => true ) );
// Edit a post with post_status 'in-review' and click "Save Draft": it is saved as 'pending'.

This PR takes the small scope discussed in comment:178 and comment:179: let registered custom statuses appear in the Publish meta box, without changing workflows, capabilities, or other screens.

Changes

  • The current post's custom status is always included in the status dropdown, its label is shown next to "Status:", and the save button reads "Save as [label]". Saving keeps the status.
  • New post_submitbox_custom_statuses filter to offer additional custom statuses in the dropdown. It receives the post, so statuses can be offered per post type. Custom statuses are opt-in, so existing sites do not suddenly see every registered status in the dropdown (see comment:135).
  • The filter value is cast to an array and duplicate statuses are rendered once.
  • Switching visibility to Private and back to Public now restores the previously selected status. Previously, for posts that were not a draft or scheduled (e.g. pending or a custom status), the "Published" option stayed selected.

Notes

  • Builds on Administration: Support custom post statuses in the Publish meta box #12836 by @Sukhendu2002, rebased on trunk with review fixes on top.
  • Classic editor Publish meta box only. Quick Edit, the block editor, the REST API, and status capabilities are not changed.
  • The filter controls presentation only and does not grant permission to use a status.
  • Custom statuses registered as public or private are not treated as published by the meta box, since core still assumes publish (see comment:181). Feedback welcome on whether those should be excluded from the dropdown.
  • An alternative to the filter would be a register_post_status() argument such as show_in_admin_status_dropdown, as proposed in comment:135. Happy to switch if that is preferred.

Testing

New PHPUnit tests in tests/phpunit/tests/admin/metaBoxes.php and a QUnit test in tests/qunit/wp-admin/js/post.js:

npm run test:php -- --filter Tests_Admin_MetaBoxes
npm run grunt qunit

Manual testing:

  1. Register a custom status, e.g. in a mu-plugin: register_post_status( 'in-review', array( 'label' => 'In Review', 'protected' => true ) );
  2. Create a post and set its status to in-review (e.g. wp post update <ID> --post_status=in-review).
  3. Open the post in the classic editor. "Status:" shows "In Review" and the button reads "Save as In Review".
  4. Click the button. The post keeps the in-review status (on trunk it becomes pending).
  5. Add the status for posts with add_filter( 'post_submitbox_custom_statuses', fn() => array( 'in-review' ) ); and confirm it appears in the status dropdown of a draft.
  6. Change visibility to Private and back to Public. The previously selected status is restored.

This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.

Previously, the classic editor's Publish meta box only rendered options for the built-in post statuses. When editing a post with a registered custom status, the Status label was empty and the status dropdown had no matching option, so the browser submitted the first option instead and saving the post silently changed its status to `pending`.

The current post's custom status is now always included in the dropdown, its label is displayed, and the save button reads "Save as [status]". The new `post_submitbox_custom_statuses` filter allows additional custom statuses to be offered. Toggling visibility to Private and back to Public now restores the previously selected status.

Developed in WordPress#12836.

See WordPress#12706.
The value returned by the `post_submitbox_custom_statuses` filter is cast to an array, so a callback returning a string or `null` no longer causes a fatal error, and duplicate statuses are only rendered once. The per-option save text uses its own variable instead of overwriting the save button's label, and the filter's `@since` tag is corrected to 7.2.0.

The tests are updated with typed methods, clearer fixture names, and coverage for non-array filter values and duplicate statuses.

See WordPress#12706.
@github-actions

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs.

Core Committers: Use this line as a base for the props when committing in SVN:

Props sabbir345.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.


Props Bot commands

You can trigger Props Bot actions by commenting on this PR:

  • @propsbot add <username> to give props to a GitHub user. Requires write access.
  • @propsbot remove <username> to leave a user out of the props. Requires write access.
  • @propsbot refresh to refresh this list. Adding the props-bot label works too.

@github-actions

Copy link
Copy Markdown

Test using WordPress Playground

The changes in this pull request can previewed and tested using a WordPress Playground instance.

WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser.

Some things to be aware of

  • All changes will be lost when closing a tab with a Playground instance.
  • All changes will be lost when refreshing the page.
  • A fresh instance is created each time the link below is clicked.
  • Every time this pull request is updated, a new ZIP file containing all changes is created. If changes are not reflected in the Playground instance,
    it's possible that the most recent build failed, or has not completed. Check the list of workflow runs to be sure.

For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation.

Test this pull request with WordPress Playground.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant