[wp-trac] [WordPress Trac] #64670: WP_REST_Posts_Controller::update_item() not passing parent to wp_unique_post_slug() for draft child

WordPress Trac noreply at wordpress.org
Wed Feb 18 17:35:30 UTC 2026


#64670: WP_REST_Posts_Controller::update_item() not passing parent to
wp_unique_post_slug() for draft child
------------------------------------------+-----------------------------
 Reporter:  esaner                        |      Owner:  (none)
     Type:  defect (bug)                  |     Status:  new
 Priority:  normal                        |  Milestone:  Awaiting Review
Component:  Permalinks                    |    Version:  6.9.1
 Severity:  normal                        |   Keywords:
  Focuses:  ui, administration, rest-api  |
------------------------------------------+-----------------------------
 Editing the slug of a draft child page (or any hierarchical post type) in
 the block editor excludes the parent slug when determining slug
 interference, despite the fact that the parent slug is shown in the
 child's permalink, just below the slug setting input.

 I believe the slug check occurs with `wp_unique_post_slug()` in
 `WP_REST_Posts_Controller::update_item()` of wp-includes/rest-
 api/endpoints/class-wp-rest-posts-controller.php:967.

 === Environment

 - WordPress 6.9.1
 - Theme: Twenty Twenty-Five 1.4
 - Plugins: none
 - PHP 8.4.14
 - nginx 1.29.3
 - mysql 9.5.0
 - macOS 15.7.3

 === Steps to Reproduce

 Permalink structure: Post name

 Steps 1–3 below can be done in multiple ways (block editor, wp-cli, etc.).

 1. Publish a page (First Page), example slug: /slug
 2. Publish another page (Parent Page), example slug: /parent
 3. Create another draft page (Child Page), set its parent to Parent Page,
 and save the draft
 4. In the block editor, edit the Child Page slug to /slug and save the
 draft; the slug will be changed to slug-2, even though the permalink just
 below the slug input shows /parent/slug and /parent/slug does not
 interfere with First Page /slug

 Additional Notes:
 - If Child Page is published, its slug can be edited to /parent/slug in
 the block editor.
 - In draft status, Child Page can have its slug edited to /parent/slug
 using quick edit in admin post list.

 === Expected Outcomes

 - Slug editing behavior for parent/child relationships should be the same
 in the block editor and admin post list quick edit.
 - If the block editor slug setting shows a parent slug incorporated into a
 child's permalink, the parent slug should also be used to determine the
 child slug's interference (regardless of the child's status).

 === Possible Solutions

 Before `wp_unique_post_slug()` is called in class-wp-rest-posts-
 controller.php:967, the following defines `$post` and `$post_parent`.

 {{{
 $post        = $this->prepare_item_for_database( $request );
 ...
 $post_parent = ! empty( $post->post_parent ) ? $post->post_parent : 0;
 }}}

 For a draft page, `$post->post_parent` comes through as null, so it's set
 to 0;

 `$post_before`, defined a few lines earlier at class-wp-rest-posts-
 controller.php:947, does contain the parent and could possibly be used to
 define `$post_parent` similar to `$post_status` at line 954. For example:

 {{{
 if ( ! empty( $post->post_parent ) ) {
     $post_parent = $post->post_parent;
 } else {
     $post_parent = $post_before->post_parent ? $post_before->post_parent :
 0;
 }
 }}}

 === Related Tickets

 In #47988 @paulbonneau noted how
 [https://core.trac.wordpress.org/ticket/47988?#Abouttheproposedsolutioninyourlastanswer
 draft and pending statuses are changed to publish] for
 `wp_unique_post_slug()` calls in `WP_REST_Posts_Controller:create_item()`
 and `WP_REST_Posts_Controller::update_item()`. That seems unusual and
 suggests room for improvement, though any changes to
 `wp_unique_post_slug()` would need careful consideration.

 I share @paulbonneau's interest in wondering,
 "[https://core.trac.wordpress.org/ticket/47988?#Whatcouldbeagoodnextstep
 Why shouldn't we assign a post_name to a post with a draft post_status?]".

 #47988 also references several other tickets related to draft status and
 `wp_unique_post_slug()`, such as #47552 and #61996.

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/64670>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list