How to Add a Custom Post Status

I couldn’t find any good information about adding custom post statuses in WordPress programmatically, so I decided to publish this tutorial about creating one.

Registering a Custom Post Status Using register_post_status()

First things first, we need to register our custom post status in WordPress. It is kind of similar to how we usually register custom post types and custom taxonomies – we use functions register_post_type() and register_taxonomy() inside the init hook. This time, we will use the register_post_status() function instead.

add_action( 'init', 'rudr_custom_status_creation' );

function rudr_custom_status_creation(){
	
	register_post_status( 
		'featured', 
		array(
			'label' => 'Featured',
			'label_count' => _n_noop( 'Featured <span class="count">(%s)</span>', 'Featured <span class="count">(%s)</span>'),
			'public' => true,
		) 
	);
}

So, you inserted this code into the functions.php file of your current theme or created a plugin for that, activated it, and… nothing happened.

Don’t get me wrong, the register_post_status() really did something and now we’re able to use our custom post status on our WordPress, but we still need to complete some extra steps in order to make it appear in our admin dashboard.

Show in Admin Status List

Let’s begin with the simplest part, ok?

If you don’t know what an admin status list is, here you go:

WordPress adding a custom post status to the admin status list

As you can see, our custom post status “Featured” is already displayed there. How have I been able to achieve that?

First of all, and it is so obvious – you need to have posts of that custom post status.

But how can we change a post status since we don’t have any admin interface for that yet? I just used the wp_update_post() function for now.

wp_update_post( array(
	'ID' => 12345,
	'post_status' => 'featured',
) );

That should probably be enough, however, let’s take a look at show_in_admin_status_list and show_in_admin_all_list arguments of the register_post_status() function.

register_post_status( 
	'featured', 
	array(
		'label' => 'Featured',
		'show_in_admin_status_list' => true,
		'show_in_admin_all_list' => true,

By default, in our case, both of them are set to true.

  • If you set show_in_admin_status_list to false – your status will disappear from the admin status list,
  • If you set show_in_admin_all_list to false, posts of your custom status won’t be counted in “All (7)”

That’s pretty much it, let’s continue and add some admin UI.

Add a Custom Post Status to Post Edit Pages

Probably, you won’t be happy after what I am going to show you now, but it is kind of a known WordPress issue, so a patch is this simple jQuery code snippet:

<?php
add_action( 'admin_footer-post.php', function() {

	?><script>
	jQuery( function( $ ) {
		// add our custom post status
		$( '#post_status' ).append( '<option value="featured">Featured</option>' )

		<?php if( 'featured' === get_post_status() ) : ?>
			$( '#post-status-display' ).text( 'Featured' )
			$( '#post_status' ).val( 'featured' )
		<?php endif; ?>
	} )
	</script>
	<?php
	
} );

Now, our custom post status is added to the WordPress post edit page:

WordPress custom post status on edit post pages

Do we need to do something with the save_post hook as well? No, when you set a custom post status in this dropdown and you registered it properly before, it will be saved without issues.

But this is for the classic editor, what about Gutenberg? Please, let me know in the comments below if you’re interested in the implementation for Gutenberg.

Add a Custom Post Status To the Quick Edit Menu

Our next step – is adding our registered custom post status into the quick edit menu, it usually appears when you click a “Quick Edit” link on the “All posts” page.

Let’s start with a code snippet first which is also based on jQuery:

<?php
add_action( 'admin_footer-edit.php', 'rudr_status_into_inline_edit' );
 
function rudr_status_into_inline_edit() {

	?><script>
	jQuery( function($) {
		$( 'select[name="_status"]' ).append( '<option value="featured">Featured</option>' );
	} );
	</script><?php

}

Some comments related to the code snippet above:

  • Insert it into your theme’s functions.php file. If you already know what you’re doing — insert it wherever you want.
  • For beginners — if your functions.php is empty, first of all, add on the first line: <?php 😁
  • admin_footer-edit.php action hook means that the code will be processed only on Post wp-admin/edit.php, Pages wp-admin/edit.php?post_type=page and Custom Post Type pages wp-admin/edit.php?post_type={custom post type} in the admin area.

And here is our result:

Custom post statuses in the Quick Edit menu

Display a Custom Post Status Label

Last but not least, I also recommend you add the following hook to your functions.php – display_post_states.

add_filter( 'display_post_states', 'rudr_display_status_label' );

function rudr_display_status_label( $states ) {

	// skip if we're already filtering by this status
	if( 'featured' === get_query_var( 'post_status' ) ) {
		return $states;
	}
	
	if( 'featured' === get_post_status() ) {
		$states[] = 'Featured';
	}
	
	return $states;

}

It will allow you to display a custom post status label near post titles like this:

Add a custom post status label in admin dashboard in WordPress

Custom Post Statuses in Simple WP Crossposting

Let’s assume that you have added a custom post status to your WordPress website and everything seems to be great, the only thing – you’re using my Simple WP Crossposting plugin and your custom status doesn’t appear in the plugin settings.

By default, my plugin doesn’t support custom post statuses because different plugins can overuse them and I don’t want my plugin settings page to be a complete mess.

That’s why you can include your post status in my plugin with this simple filter hook:

add_filter( 'rudr_swc_post_statuses', function( $post_statuses ) {

	$post_statuses[] = 'featured';
	return $post_statuses;
	
} );

if you’re not 100% sure, where to use this code, please check this guide.

Here you go:

Add a custom post status to the Simple WP Crossposting plugin settings.

That’s it. Please leave a comment if you have a question.

Thanks for reading.

Misha Rudrastyh

Misha Rudrastyh

Hey guys and welcome to my website. For more than 15 years I've been doing my best to share with you some superb WordPress guides and tips for free.

Need some developer help? Contact me

Follow me on X