From 0b6e1b7d5f5f01c8c99f3fb31d8359ddf53c77e7 Mon Sep 17 00:00:00 2001
From: Poli Gilad <83961704+poligilad-auto@users.noreply.github.com>
Date: Wed, 24 Jun 2026 15:00:51 +0200
Subject: [PATCH 1/2] Editor: Use radio buttons for Classic Editor status
---
src/js/_enqueues/admin/post.js | 114 ++++++++++++++----
src/wp-admin/css/edit.css | 7 ++
src/wp-admin/includes/meta-boxes.php | 34 +++---
.../phpunit/tests/admin/includesMetaBoxes.php | 48 ++++++++
4 files changed, 165 insertions(+), 38 deletions(-)
create mode 100644 tests/phpunit/tests/admin/includesMetaBoxes.php
diff --git a/src/js/_enqueues/admin/post.js b/src/js/_enqueues/admin/post.js
index d50fe6007d33b..9b8d7580170ec 100644
--- a/src/js/_enqueues/admin/post.js
+++ b/src/js/_enqueues/admin/post.js
@@ -303,6 +303,8 @@ window.wp = window.wp || {};
*/
jQuery( function($) {
var stamp, visibility, $submitButtons, updateVisibility, updateText,
+ getPostStatusValue, setPostStatusValue, getPostStatusLabel,
+ ensurePublishPostStatus, removePublishPostStatus,
$textarea = $('#content'),
$document = $(document),
postId = $('#post_ID').val() || 0,
@@ -721,6 +723,81 @@ jQuery( function($) {
stamp = $('#timestamp').html();
visibility = $('#post-visibility-display').html();
+ /**
+ * Get the selected post status value.
+ *
+ * @ignore
+ *
+ * @return {string} Selected post status value.
+ */
+ getPostStatusValue = function() {
+ return $postStatusSelect.find('input[name="post_status"]:checked').val();
+ };
+
+ /**
+ * Set the selected post status value.
+ *
+ * @ignore
+ *
+ * @param {string} value Post status value.
+ *
+ * @return {void}
+ */
+ setPostStatusValue = function( value ) {
+ $postStatusSelect.find('input[name="post_status"][value="' + value + '"]').prop('checked', true);
+ };
+
+ /**
+ * Get the selected post status label.
+ *
+ * @ignore
+ *
+ * @return {string} Selected post status label.
+ */
+ getPostStatusLabel = function() {
+ var $checked = $postStatusSelect.find('input[name="post_status"]:checked');
+
+ if ( ! $checked.length ) {
+ return '';
+ }
+
+ return $postStatusSelect.find('label[for="' + $checked.attr('id') + '"]').text();
+ };
+
+ /**
+ * Ensure a publish status radio exists and is selected.
+ *
+ * @ignore
+ *
+ * @param {string} label Publish status label.
+ *
+ * @return {void}
+ */
+ ensurePublishPostStatus = function( label ) {
+ var $publishStatus = $postStatusSelect.find('input[name="post_status"][value="publish"]');
+
+ if ( ! $publishStatus.length ) {
+ $postStatusSelect.find('.post-status-options').prepend(
+ '
'
+ );
+ $publishStatus = $postStatusSelect.find('input[name="post_status"][value="publish"]');
+ }
+
+ $publishStatus.siblings('label').text( label );
+ setPostStatusValue('publish');
+ };
+
+ /**
+ * Remove a dynamically added publish status radio.
+ *
+ * @ignore
+ *
+ * @return {void}
+ */
+ removePublishPostStatus = function() {
+ $postStatusSelect.find('input[name="post_status"][value="publish"]').closest('.post-status-option').remove();
+ };
+
/**
* When the visibility of a post changes sub-options should be shown or hidden.
*
@@ -757,8 +834,8 @@ jQuery( function($) {
if ( ! $timestampdiv.length )
return true;
- var attemptedDate, originalDate, currentDate, publishOn, postStatus = $('#post_status'),
- optPublish = $('option[value="publish"]', postStatus), aa = $('#aa').val(),
+ var attemptedDate, originalDate, currentDate, publishOn, postStatusValue,
+ aa = $('#aa').val(),
mm = $('#mm').val(), jj = $('#jj').val(), hh = $('#hh').val(), mn = $('#mn').val();
attemptedDate = new Date( aa, mm - 1, jj, hh, mn );
@@ -823,41 +900,34 @@ jQuery( function($) {
// Add "privately published" to post status when applies.
if ( $postVisibilitySelect.find('input:radio:checked').val() == 'private' ) {
$('#publish').val( __( 'Update' ) );
- if ( 0 === optPublish.length ) {
- postStatus.append('');
- } else {
- optPublish.html( __( 'Privately Published' ) );
- }
- $('option[value="publish"]', postStatus).prop('selected', true);
+ ensurePublishPostStatus( __( 'Privately Published' ) );
$('#misc-publishing-actions .edit-post-status').hide();
} else {
- if ( $('#original_post_status').val() == 'future' || $('#original_post_status').val() == 'draft' ) {
- if ( optPublish.length ) {
- optPublish.remove();
- postStatus.val($('#hidden_post_status').val());
+ if ( $('#original_post_status').val() == 'future' || $('#original_post_status').val() == 'draft' || $('#original_post_status').val() == 'auto-draft' ) {
+ if ( $postStatusSelect.find('input[name="post_status"][value="publish"]').length ) {
+ removePublishPostStatus();
+ setPostStatusValue($('#hidden_post_status').val());
}
} else {
- optPublish.html( __( 'Published' ) );
+ $postStatusSelect.find('input[name="post_status"][value="publish"]').siblings('label').text( __( 'Published' ) );
}
- if ( postStatus.is(':hidden') )
+ if ( $postStatusSelect.is(':hidden') )
$('#misc-publishing-actions .edit-post-status').show();
}
// Update "Status:" to currently selected status.
$('#post-status-display').text(
// Remove any potential tags from post status text.
- wp.sanitize.stripTagsAndEncodeText( $('option:selected', postStatus).text() )
+ wp.sanitize.stripTagsAndEncodeText( getPostStatusLabel() )
);
// Show or hide the "Save Draft" button.
- if (
- $('option:selected', postStatus).val() == 'private' ||
- $('option:selected', postStatus).val() == 'publish'
- ) {
+ postStatusValue = getPostStatusValue();
+ if ( postStatusValue == 'private' || postStatusValue == 'publish' ) {
$('#save-post').hide();
} else {
$('#save-post').show();
- if ( $('option:selected', postStatus).val() == 'pending' ) {
+ if ( postStatusValue == 'pending' ) {
$('#save-post').show().val( __( 'Save as Pending' ) );
} else {
$('#save-post').show().val( __( 'Save Draft' ) );
@@ -973,7 +1043,7 @@ jQuery( function($) {
$postStatusSelect.siblings('a.edit-post-status').on( 'click', function( event ) {
if ( $postStatusSelect.is( ':hidden' ) ) {
$postStatusSelect.slideDown( 'fast', function() {
- $postStatusSelect.find('select').trigger( 'focus' );
+ $postStatusSelect.find('input[type="radio"]').first().trigger( 'focus' );
} );
$(this).hide();
}
@@ -990,7 +1060,7 @@ jQuery( function($) {
// Cancel Post Status editing and hide the options.
$postStatusSelect.find('.cancel-post-status').on( 'click', function( event ) {
$postStatusSelect.slideUp( 'fast' ).siblings( 'a.edit-post-status' ).show().trigger( 'focus' );
- $('#post_status').val( $('#hidden_post_status').val() );
+ setPostStatusValue( $('#hidden_post_status').val() );
updateText();
event.preventDefault();
});
diff --git a/src/wp-admin/css/edit.css b/src/wp-admin/css/edit.css
index f1dd76ac31474..229a8b26dc8a3 100644
--- a/src/wp-admin/css/edit.css
+++ b/src/wp-admin/css/edit.css
@@ -706,12 +706,19 @@ form#tags-filter {
font-weight: 600;
}
+#post-status-select,
#post-visibility-select,
#comment-status-radio {
line-height: 1.5;
margin-top: 3px;
}
+#post-status-select .post-status-options {
+ border: 0;
+ margin: 0 0 0.7em;
+ padding: 0;
+}
+
#linksubmitdiv .inside, /* Old Link Manager back-compat. */
#poststuff #submitdiv .inside {
margin: 0;
diff --git a/src/wp-admin/includes/meta-boxes.php b/src/wp-admin/includes/meta-boxes.php
index 535a00cd3fe94..2de43685d37fa 100644
--- a/src/wp-admin/includes/meta-boxes.php
+++ b/src/wp-admin/includes/meta-boxes.php
@@ -141,29 +141,31 @@ function post_submit_meta_box( $post, $args = array() ) {
-
-
-
-
+
+
+
+
+
user->create( array( 'role' => 'administrator' ) );
+ }
+
+ public function set_up() {
+ parent::set_up();
+
+ require_once ABSPATH . 'wp-admin/includes/meta-boxes.php';
+
+ wp_set_current_user( self::$admin_id );
+ }
+
+ public function test_post_submit_meta_box_status_controls_are_rendered_as_radios() {
+ $post = self::factory()->post->create_and_get( array( 'post_status' => 'draft' ) );
+ $output = $this->get_post_submit_meta_box_output( $post );
+
+ $this->assertStringNotContainsString( '