How to Implement Custom Post Statuses in WordPress

Posted on 16th June 2023

Introduction

As a WordPress plugin developer, you may find yourself in need of adding a custom post status to a post type. This could be for any number of reasons, but a common one is to indicate the status of a post. For example, you may want to mark a post as “in progress” or “pending review”.

In this article, we will show you how to add custom post statuses to a post type in WordPress. We will also cover how to display custom post statuses in the WordPress admin area, and how to filter posts by custom post status.

Adding a Custom Post Status

Adding a custom post status is relatively simple. You just need to use the register_post_status() function. This function takes two arguments: the post status slug and an array of arguments.

The post status slug is the key that will be used to identify this post status. It should be a lowercase string with no spaces. For our example, we will use “in-progress”.

The array of arguments is where we define how our custom post status will behave. The most important argument is label. This is the label that will be used to identify our custom post status in the WordPress admin area. Other arguments include:

  • public – Whether posts of this status should be publicly visible. Default is false.
  • show_in_admin_all_list – Whether to include posts of this status in the “All Posts” list table. Default is true.
  • show_in_admin_status_list – Whether to include posts of this status in the “Status” filter dropdown. Default is true.

Here is an example of how to register a custom post status:

// Register a custom post status called "In Progress"
register_post_status( 'in-progress', array(
	'label'                     => _x( 'In Progress', 'post' ),
	'public'                    => false,
	'show_in_admin_all_list'    => true,
	'show_in_admin_status_list' => true,
) );

Once you have registered your custom post status, you need to add it to a post type. You can do this by using the register_post_type() function and setting the supports argument to 'status'. This will add a post status selector to the post editor for that post type.

For example, if we wanted to add our “In Progress” post status to the “Posts” post type, we would use the following code:

// Add a post status selector to the "Posts" post type
add_action( 'init', 'wpse126301_init' );
function wpse126301_init() {
	register_post_type( 'post', array(
		'supports' => array( 'status' ),
	) );
}

Displaying Custom Post Statuses in the WordPress Admin Area

Once you have added your custom post status to a post type, it will be selectable in the post editor. However, it will not be visible in the “All Posts” list table. This is because the default behavior is to only show “Published” and “Scheduled” posts in this list.

If you want to display posts of your custom post status in the “All Posts” list table, you need to set the show_in_admin_all_list argument to true when registering your custom post status. For example:

// Register a custom post status called "In Progress"
register_post_status( 'in-progress', array(
	'label'                     => _x( 'In Progress', 'post' ),
	'public'                    => false,
	'show_in_admin_all_list'    => true, // Show in "All Posts" list
	'show_in_admin_status_list' => true,
) );

Once you have done this, posts of your custom post status will be visible in the “All Posts” list table. They will be identified by their post status label (e.g. “In Progress”).

Filtering Posts by Custom Post Status

If you want to filter posts by custom post status in the WordPress admin area, you need to set the show_in_admin_status_list argument to true when registering your custom post status. For example:

// Register a custom post status called "In Progress"
register_post_status( 'in-progress', array(
	'label'                     => _x( 'In Progress', 'post' ),
	'public'                    => false,
	'show_in_admin_all_list'    => true,
	'show_in_admin_status_list' => true, // Show in "Status" filter
) );

Once you have done this, a “Status” filter will be added to the “All Posts” list table. This filter will include your custom post status. Posts of your custom post status will be identified by their post status label (e.g. “In Progress”).

Once you have decided which custom post statuses you want to use on your WordPress site, you need to register them. You can do this by adding some code to your theme’s functions.php file or by using a plugin.

If you are comfortable editing code, you can add this code to your theme’s functions.php file:

function register_my_custom_post_status(){
register_post_status( ‘draft’, array(
‘label’ => _x( ‘Draft’, ‘post status label’, ‘textdomain’ ),
‘public’ => false,
‘show_in_admin_all_list’ => false,
‘show_in_admin_status_list’ => true,
‘label_count’ => _n_noop( ‘Draft (%s)‘, ‘Drafts (%s)‘, ‘textdomain’ ),
) );
register_post_status( ‘pending’, array(
‘label’ => _x( ‘Pending’, ‘post status label’, ‘textdomain’ ),
‘public’ => false,
‘show_in_admin_all_list’ => true,
‘show_in_admin_status_list’ => true,
‘label_count’ => _n_noop( ‘Pending (%s)‘, ‘Pending (%s)‘, ‘textdomain’ ),
) );
register_post_status( ‘future’, array(
‘label’ => _x( ‘Future’, ‘post status label’, ‘textdomain’ ),
‘public’ => false,
‘show_in_admin_all_list’ => true,
‘show_in_admin_status_list’ => true,
‘label_count’ => _n_noop( ‘Future (%s)‘, ‘Future (%s)‘, ‘textdomain’ ),
) );
}
add_action( ‘init’, ‘register_my_custom_post_status’ );

This code registers three custom post statuses: draft, pending, and future. You can add as many or as few custom post statuses as you like.

If you are not comfortable editing code, you can use a plugin like Custom Post Status Manager. This plugin makes it easy to add, remove, and change custom post statuses.

Once you have registered your custom post statuses, you need to add them to your post type. You can do this by adding some code to your theme’s functions.php file or by using a plugin.

If you are comfortable editing code, you can add this code to your theme’s functions.php file:

function add_my_custom_post_status( $post_status, $post_type ) {
if ( $post_type == ‘post’ ) {
$post_status[‘draft’] = _x( ‘Draft’, ‘post status label’, ‘textdomain’ );
$post_status[‘pending’] = _x( ‘Pending’, ‘post status label’, ‘textdomain’ );
$post_status[‘future’] = _x( ‘Future’, ‘post status label’, ‘textdomain’ );
}
return $post_status;
}
add_filter( ‘register_post_status’, ‘add_my_custom_post_status’, 10, 2 );

This code adds the custom post statuses to the post type. You can add as many or as few custom post statuses as you like.

If you are not comfortable editing code, you can use a plugin like Custom Post Status Manager. This plugin makes it easy to add, remove, and change custom post statuses.