Adding a Custom Post Status in WordPress Plugin

Posted on 20th June 2023

Adding a Custom Post Status in WordPress Plugin

One of the great things about WordPress is its extensibility. Developers can tap into the vast amount of functionality that WordPress provides by creating plugins. And one of the most powerful features of plugins is the ability to add custom post types and custom post statuses.

In this article, we will show you how to add a custom post status to a WordPress plugin. We will also discuss why and when you would want to use custom post statuses in your plugins.

What is a Custom Post Status?

In WordPress, every post has a post status. The default post statuses in WordPress are:

Publish

Pending

Draft

Auto-Draft

Future

Private

Inherit

Trash

Most of these statuses are pretty self-explanatory. A post can be published, pending, or draft. A post can also be in the trash.

But what if you want to create a custom post status? For example, let’s say you are developing a plugin that allows users to submit articles for review. Once an article is submitted, it should have a post status of “Pending Review.” Once the article is approved, the post status should be changed to “Published.”

This is where custom post statuses come in handy. By default, WordPress does not have a “Pending Review” post status. But with a few lines of code, we can easily add one.

Adding a Custom Post Status

Adding a custom post status in WordPress is fairly simple. All you need to do is register the post status using the register_post_status() function.

Here is an example of how you would register a custom post status called “Pending Review”:

function wpdocs_register_post_status() {
register_post_status( ‘pending_review’, array(
‘label’ => _x( ‘Pending Review’, ‘post status label’ ),
‘public’ => true,
‘show_in_admin_all_list’ => true,
‘show_in_admin_status_list’ => true,
‘label_count’ => _n_noop( ‘Pending Review (%s)’, ‘Pending Reviews (%s)’ ),
) );
}
add_action( ‘init’, ‘wpdocs_register_post_status’ );
This code goes in your theme’s functions.php file or in a custom plugin.

Let’s take a look at each parameter in the register_post_status() function and see what it does.

The first parameter is the post status ID. In our example, we are using “pending_review”.

The second parameter is an array of arguments. The label parameter is the post status label. The public parameter is set to true because we want this post status to be publicly visible.

The show_in_admin_all_list and show_in_admin_status_list parameters are set to true because we want this post status to be visible in the WordPress admin.

The label_count parameter is used to display the number of posts with this status. In our example, we are using a _n_noop() function. This function allows us to internationalize our plugin.

Once you have registered the post status, you need to add it to the list of post statuses for the relevant post types. You can do this using the register_post_status() function again.

Here is an example of how you would add the “Pending Review” post status to the “post” post type:

function wpdocs_add_post_status() {
register_post_status( ‘post’, array(
‘post_type’ => array( ‘post’ ),
‘show_in_admin_all_list’ => true,
‘show_in_admin_status_list’ => true,
‘label_count’ => _n_noop( ‘Pending Review (%s)’, ‘Pending Reviews (%s)’ ),
) );
}
add_action( ‘init’, ‘wpdocs_add_post_status’ );
This code goes in your theme’s functions.php file or in a custom plugin.

As you can see, we are using the register_post_status() function again. But this time, we are using it to add the post status to the post type.

The first parameter is the post type. In our example, we are using “post”.

The second parameter is an array of arguments. The show_in_admin_all_list and show_in_admin_status_list parameters are set to true because we want this post status to be visible in the WordPress admin.

The label_count parameter is used to display the number of posts with this status. In our example, we are using a _n_noop() function. This function allows us to internationalize our plugin.

Once you have registered the post status and added it to the relevant post types, you need to add it to the post status drop-down in the WordPress admin.

You can do this by using the post_status_labels filter. This filter allows you to modify the post status labels.

Here is an example of how you would add the “Pending Review” post status to the post status drop-down in the WordPress admin:

function wpdocs_add_post_status_labels( $post_status_labels ) {
$post_status_labels[‘pending_review’] = _x( ‘Pending Review’, ‘post status label’ );
return $post_status_labels;
}
add_filter( ‘post_status_labels’, ‘wpdocs_add_post_status_labels’ );
This code goes in your theme’s functions.php file or in a custom plugin.

As you can see, we are using the post_status_labels filter to add our custom post status label to the WordPress admin.

The first parameter is the $post_status_labels array. This is an array of all the post status labels.

The second parameter is the post status ID. In our example, we are using “pending_review”.

The third parameter is the post status label. In our example, we are using _x() function to internationalize our plugin.

Once you have added the custom post status to the WordPress admin, you need to add it to the front-end of your website.

You can do this by using the display_post_states filter. This filter allows you to add custom post states to the front-end of your website.

Here is an example of how you would add the “Pending Review” post status to the front-end of your website:

function wpdocs_add_post_status_states( $post_states, $post ) {
if ( $post->post_status == ‘pending_review’ ) {
$post_states[] = _x( ‘Pending Review’, ‘post status label’ );
}
return $post_states;
}
add_filter( ‘display_post_states’, ‘wpdocs_add_post_status_states’, 10, 2 );
This code goes in your theme’s functions.php file or in a custom plugin.

As you can see, we are using the display_post_states filter to add our custom post status to the front-end of our website.

The first parameter is the $post_states array. This is an array of all the post states.

The second parameter is the $post object. This is the post object for the current post.

The third parameter is the post status. In our example, we are using “pending_review”.

The fourth parameter is the post status label. In our example, we are using _x() function to internationalize our plugin.

Once you have added the custom post status to the WordPress admin and the front-end of your website, you need to add it to the WordPress REST API.

You can do this by using the rest_api_allowed_post_status filter. This filter allows you to add custom post statuses to the WordPress REST API.

Here is an example of how you would add the “Pending Review” post status to the WordPress REST API:

function wpdocs_add_post_status_rest_api( $allowed_statuses, $post_type ) {
if ( $post_type === ‘post’ ) {
$allowed_statuses[] = ‘pending_review’;
}
return $allowed_statuses;
}
add_filter( ‘rest_api_allowed_post_status’, ‘wpdocs_add_post_status_rest_api’, 10, 2 );
This code goes in your theme’s functions.php file or in a custom plugin.

As you can see, we are using the rest_api_allowed_post_status filter to add our custom post status to the