Make WordPress Core

Opened 5 years ago

Closed 4 weeks ago

#51403 closed enhancement (fixed)

Add filter for _post_states as it outputs raw HTML

Reported by: brandbrilliance's profile brandbrilliance Owned by: westonruter's profile westonruter
Milestone: 6.9 Priority: normal
Severity: normal Version:
Component: Posts, Post Types Keywords: dev-reviewed
Focuses: template Cc:

Description

Currently this function can't be overridden with a filter, so it outputs raw HTML separators and such directly into the post title in the edit screen. However it should be suggested to make it possible to display the post states in your own custom function, e.g. remove the separators and the divider with the title, which are currently hard-coded at the moment in the function as raw HTML?

Change History (32)

#1 @SirLouen
3 months ago

  • Focuses coding-standards removed
  • Keywords needs-patch good-first-bug has-test-info added
  • Milestone changed from Awaiting Review to Future Release
  • Version 5.5.1 deleted

Looks good to me. A filter to post_states_string can be applied here definitely.

Testing Instructions after the patch

Test info is pretty straight forward. These states are the ones that appear near the list of posts for example (The list that can say something like "Front Page, Draft", for example.

https://i.imgur.com/v4Ya1bN.png

So testing is simply adding the filter, and checking if it appears there the modified content as expected. Like this:

https://i.imgur.com/UF05Wmk.png

This ticket was mentioned in PR #10000 on WordPress/wordpress-develop by @paulbonneau.


3 months ago
#2

  • Keywords has-patch added; needs-patch removed

This PR aim to implement a new filter in _post_states as asked in the ticket linked below

#3 @paulbonneau
3 months ago

Hello @SirLouen @brandbrilliance,

I created a PR with an implementation attempt of what you described @SirLouen.

The new filter can be tested by adding the code below to a test theme functions.php or test plugin :

<?php
add_filter('post_states_string', function($post_states_string, $post){
    return $post_states_string .= '<span class="post-state">, Sample state</span>';
}, 10, 2);

Nevertheless I'm not sure that a filter in _post_states function (/wp-admin/includes/template.php l.2248) is necessary.

_post_states seems to be a formatting function specifically designed to display post states in the WordPress admin post list view.

The use case described by @brandbrilliance seems already covered. One can totally use the get_post_states function to gather post state and format them as you want on another screen sans passer par la fonction _post_states.

#4 @paulbonneau
3 months ago

  • Keywords has-unit-tests added

Added test and a doc block above the new filter as suggested by @mukeshpanchal27 in the Github PR https://github.com/WordPress/wordpress-develop/pull/10000

#5 follow-ups: @mukesh27
3 months ago

  • Milestone changed from Future Release to 6.9

Move into milestone for visibility.

@mukesh27 commented on PR #10000:


3 months ago
#6

Thanks @paulbonneau, Left some final bit of feedbacks.

#7 in reply to: ↑ 5 @SirLouen
3 months ago

  • Keywords needs-testing added

#8 in reply to: ↑ 5 @SirLouen
3 months ago

  • Owner set to SirLouen
  • Status changed from new to reviewing

Replying to mukesh27:

Move into milestone for visibility.

@paulbonneau we also have here the compact-utf8.php fixes. This fix is plaguing all PR.

@paulbonneau commented on PR #10000:


3 months ago
#9

Remove the src/wp-includes/compat-utf8.php

done

This ticket was mentioned in Slack in #core-test by sirlouen. View the logs.


3 months ago

This ticket was mentioned in PR #10077 on WordPress/wordpress-develop by @shsajalchowdhury.


3 months ago
#11

Trac ticket: [Add filter for _post_states as it outputs raw HTML

](https://core.trac.wordpress.org/ticket/51403)

#12 @aialvi
3 months ago

Test Report

Description

This report validates whether the indicated patch works as expected.

Patch tested: https://github.com/WordPress/wordpress-develop/pull/10000

Environment

  • WordPress: 6.9-alpha-60093-src
  • PHP: 8.2.28
  • Server: nginx/1.27.4
  • Database: mysqli (Server: 8.4.4 / Client: mysqlnd 8.2.28)
  • Browser: Chrome 140.0.0.0
  • OS: macOS
  • Theme: Twenty Twenty-Five 1.3
  • MU Plugins: None activated
  • Plugins:
    • Test Reports 1.2.0

Actual Results

  1. ✅ Issue resolved with patch.

Additional Notes

  • None

#13 @shsajalchowdhury
3 months ago

Test Report

Description

This report validates whether the indicated patch works as expected.

Testing Instructions

I have followed the instructions and applied them in my environment, and it seems to be working as instructed.

Patch tested: https://github.com/WordPress/wordpress-develop/pull/10000

Environment

  • WordPress: 6.9-alpha-60093-src
  • PHP: 8.2.29
  • Server: nginx/1.29.1
  • Database: mysqli (Server: 8.4.6 / Client: mysqlnd 8.2.29)
  • Browser: Chrome 140.0.0.0
  • OS: macOS
  • Theme: Twenty Twenty-Five 1.3
  • MU Plugins: None activated
  • Plugins:
    • Test Reports 1.2.0

Actual Results

  1. ✅ Issue resolved with patch.

Additional Notes

  • None
Last edited 3 months ago by shsajalchowdhury (previous) (diff)

#14 @SirLouen
3 months ago

  • Keywords needs-testing removed

#15 @SirLouen
3 months ago

Ok, this has been fully reviewed, tested, and everything, so it's pretty much ready to be shipped.

#16 @ugyensupport
3 months ago

Add filter for _post_states as it outputs raw HTML

Description

Currently this function can't be overridden with a filter, so it outputs raw HTML separators and such directly into the post title in the edit screen. However it should be suggested to make it possible to display the post states in your own custom function, e.g. remove the separators and the divider with the title, which are currently hard-coded at the moment in the function as raw HTML?

Patch tested: https://github.com/WordPress/wordpress-develop/pull/10000

Environment

  • WordPress: 6.8.3-alpha-60773
  • PHP: 8.4.1
  • Server: nginx/1.21.4
  • Database: mysqli (Server: 5.7.44-log / Client: mysqlnd 8.4.1)
  • Browser: Chrome 140.0.0.0
  • OS: macOS
  • Theme: Twenty Twenty-Five 1.3
  • MU Plugins: None activated
  • Plugins:
    • Gutenberg 21.7.0
    • Test Reports 1.2.0
    • WordPress Beta Tester 3.6.4

Expected Results

  1. ✅ Issue resolved with patch.

This ticket was mentioned in Slack in #core by welcher. View the logs.


8 weeks ago

#18 @westonruter
8 weeks ago

  • Owner changed from SirLouen to westonruter

#19 @westonruter
8 weeks ago

  • Resolution set to fixed
  • Status changed from reviewing to closed

In 60986:

Posts, Post Types: Add post_states_string filter for HTML string of post states.

Developed in https://github.com/WordPress/wordpress-develop/pull/10000

Props paulbonneau, mukesh27, westonruter, SirLouen, dmsnell, brandbrilliance, shsajalchowdhury, aialvi, ugyensupport.
Fixes #51403.

#21 @dmsnell
8 weeks ago

can follow-up after merge, but it would be really handy to have some examples here so people know what to expect. I find the combination of _string and HTML string confusing, plus I don’t know what to expect for this or the following array. Which post states are these?

the filter name might also be confusing especially in relation to the display_post_states filter.

<?php
/**
 * Filters the default post display states used in the posts list table.
 *
 * @since 2.8.0
 * @since 3.6.0 Added the `$post` parameter.
 * @since 5.5.0 Also applied in the Customizer context. If any admin functions
 *              are used within the filter, their existence should be checked
 *              with `function_exists()` before being used.
 *
 * @param string[] $post_states An array of post display states.
 * @param WP_Post  $post        The current post object.
 */
return apply_filters( 'display_post_states', $post_states, $post );

Might this be something more like post_states_combined_html? Alternatively, this prints a sequence of SPAN elements and text nodes. Would we accomplish a similar result if we wrapped the HTML in a containing element with an ID or class name that someone could target with the HTML API if they wanted to modify the string as a whole?

It seems to me like it’d be more useful to filter the function which generates this HTML rather than a filter which passes the already-processed HTML.

E.g. this filter leaves the specifics about the spans and &mdash; for the filtering function to remove and change. In another construction we could pass the post statuses into the filter for combination.

<?php
$html = apply_filters( 'post_states_to_html', null, $post_states, $post );
if ( ! isset( $html ) ) {
        // Do what is already in `_post_states()`;
}
<?php
add_filter( 'post_states_to_html', static function ( $html, $post_states, $post ) {
        if ( is_string( $html ) ) {
                return $html;
        }

        $html = '<ul class="post-states-list">';
        foreach ( $post_states as $post_state ) {
                $html .= '<li class="post-state">' . esc_html( $post_state ) . '</li>';
        }
        $html .= '<li class="post-state">Sample State</li>';
        $html .= '</ul>';

        return $html;
} );

#23 @westonruter
8 weeks ago

  • Resolution fixed deleted
  • Status changed from closed to reopened

@dmsnell I've opened https://github.com/WordPress/wordpress-develop/pull/10360 to iterate on this further.

In the last example you just commented, I don't think we need to go the route of a “pre” filter. Overriding the previously-constructed HTML via filter seems appropriate since this isn't an expensive operation. In regards to refactoring to encourage using a UL, I'm wary of the markup changes and back-compat.

#24 @dmsnell
8 weeks ago

Thanks @westonruter — to be clear I wasn’t proposing we change the markup; I was merely trying to think of a use-case for this filter that was more than adding plaintext after the list of post states.

My main confusion is that display_post_states sounds much more like the filter I would seek out to replace the generated HTML in wp-admin than post_states_string. It still seems like there could be some more specific vocabulary escaping us on that one.

But the improved docblock comments are gold. I can see in your changes that I was wrong on the data type for $post_states, which only confirms to me the need for them.

#25 @westonruter
8 weeks ago

In 60993:

Posts, Post Types: Rename new post_states_string filter to post_states_html.

Add examples to the PHPDoc for the filter params.

Developed in https://github.com/WordPress/wordpress-develop/pull/10360

Follow-up to [60986].

Props dmsnell, westonruter.
See #51403.

#27 @jorbin
8 weeks ago

  • Resolution set to fixed
  • Status changed from reopened to closed

With beta1 fast approaching this, marking this as fixed. If there are more changes necessary I suggest opening a follow-up ticket.

#28 @desrosj
4 weeks ago

The miscellaneous developer-focused changes developer note mentioned the new post_states_html hook introduced in [60986]/[60993] but did not cover its usage in depth: https://make.wordpress.org/core/2025/11/17/miscellaneous-developer-focused-changes-in-6-9/.

#29 @johnbillion
4 weeks ago

In 61261:

Docs: Correct the syntax of the $post_states parameter in some filters.

Follow up to r60993.

See #51403

#30 @johnbillion
4 weeks ago

  • Keywords dev-feedback added; good-first-bug has-test-info has-patch has-unit-tests removed
  • Resolution fixed deleted
  • Status changed from closed to reopened

@westonruter Reopening to request that r61261 is backported to the 6.9 branch. This particular syntax error trips up PHP-Parser which is used by various tools to parse docblocks in core.

#31 @westonruter
4 weeks ago

  • Keywords dev-reviewed added; dev-feedback removed

@johnbillion Ooof. My “improvements” to the phpdoc were clearly not (string<string, string> is just wrong). Thanks for fixing that. Backport approved ✅

#32 @johnbillion
4 weeks ago

  • Resolution set to fixed
  • Status changed from reopened to closed

In 61266:

Docs: Correct the syntax of the $post_states parameter in some filters.

Merges r61261 to the 6.9 branch.

Reviewed By westonruter

Fixes #51403

Note: See TracTickets for help on using tickets.