Skip to content

Commit 1dad4e6

Browse files
committed
Add post_title_child_separator filter
Introduces the `post_title_child_separator` filter in `WP_Posts_List_Table::column_title()`, allowing the hardcoded em-dash hierarchy indicator to be replaced with a custom string. The separator string is passed through the filter once and then repeated per hierarchy level. Renames the internal `$pad` variable to `$separator` for clarity. Fixes #39106.
1 parent e12ddb3 commit 1dad4e6

2 files changed

Lines changed: 94 additions & 3 deletions

File tree

src/wp-admin/includes/class-wp-posts-list-table.php

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1137,7 +1137,16 @@ public function column_title( $post ) {
11371137
echo '<div class="locked-info"><span class="locked-avatar">' . $locked_avatar . '</span> <span class="locked-text">' . $locked_text . "</span></div>\n";
11381138
}
11391139

1140-
$pad = str_repeat( '&#8212; ', $this->current_level );
1140+
/**
1141+
* Filters the string used to indicate hierarchy level in the posts list table.
1142+
*
1143+
* The string is repeated once per level, so a child two levels deep will
1144+
* have the separator string prepended twice.
1145+
*
1146+
* @param string $separator The string used to indicate hierarchy level. Default '&#8212; '.
1147+
* @param WP_Post $post The current post object.
1148+
*/
1149+
$separator = str_repeat( apply_filters( 'post_title_child_separator', '&#8212; ', $post ), $this->current_level );
11411150
echo '<strong>';
11421151

11431152
$title = _draft_or_post_title();
@@ -1146,13 +1155,13 @@ public function column_title( $post ) {
11461155
printf(
11471156
'<a class="row-title" href="%s">%s%s</a>',
11481157
get_edit_post_link( $post->ID ),
1149-
$pad,
1158+
$separator,
11501159
$title
11511160
);
11521161
} else {
11531162
printf(
11541163
'<span>%s%s</span>',
1155-
$pad,
1164+
$separator,
11561165
$title
11571166
);
11581167
}

tests/phpunit/tests/admin/wpPostsListTable.php

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,88 @@ public function test_empty_trash_button_should_not_be_shown_if_there_are_no_post
309309
$this->assertStringNotContainsString( 'id="delete_all"', $output );
310310
}
311311

312+
/**
313+
* Tests that the default em-dash separator is output for child pages.
314+
*
315+
* @ticket 39106
316+
*
317+
* @covers WP_Posts_List_Table::column_title
318+
*/
319+
public function test_column_title_uses_default_separator_for_child_pages() {
320+
// A child page has post_parent > 0, so column_title() will auto-calculate current_level.
321+
$child = self::$children[1][1];
322+
323+
$this->table->set_hierarchical_display( true );
324+
325+
ob_start();
326+
$this->table->column_title( $child );
327+
$output = ob_get_clean();
328+
329+
$this->assertStringContainsString( '&#8212; ', $output );
330+
}
331+
332+
/**
333+
* Tests that the post_title_child_separator filter replaces the separator.
334+
*
335+
* @ticket 39106
336+
*
337+
* @covers WP_Posts_List_Table::column_title
338+
*/
339+
public function test_post_title_child_separator_filter_changes_separator() {
340+
$child = self::$children[1][1];
341+
342+
$this->table->set_hierarchical_display( true );
343+
344+
add_filter(
345+
'post_title_child_separator',
346+
static function () {
347+
return '> ';
348+
}
349+
);
350+
351+
ob_start();
352+
$this->table->column_title( $child );
353+
$output = ob_get_clean();
354+
355+
remove_all_filters( 'post_title_child_separator' );
356+
357+
$this->assertStringContainsString( '> ', $output );
358+
$this->assertStringNotContainsString( '&#8212; ', $output );
359+
}
360+
361+
/**
362+
* Tests that the post_title_child_separator filter receives the current WP_Post object.
363+
*
364+
* @ticket 39106
365+
*
366+
* @covers WP_Posts_List_Table::column_title
367+
*/
368+
public function test_post_title_child_separator_filter_receives_post_object() {
369+
$child = self::$children[1][1];
370+
371+
$this->table->set_hierarchical_display( true );
372+
373+
$received_post = null;
374+
add_filter(
375+
'post_title_child_separator',
376+
static function ( $separator, $post ) use ( &$received_post ) {
377+
$received_post = $post;
378+
return $separator;
379+
},
380+
10,
381+
2
382+
);
383+
384+
ob_start();
385+
$this->table->column_title( $child );
386+
ob_get_clean();
387+
388+
remove_all_filters( 'post_title_child_separator' );
389+
390+
$this->assertInstanceOf( WP_Post::class, $received_post );
391+
$this->assertSame( $child->ID, $received_post->ID );
392+
}
393+
312394
/**
313395
* @ticket 42066
314396
*

0 commit comments

Comments
 (0)