Registers a post status. Do not use before init.
Description
A simple function for creating or modifying a post status based on the parameters given. The function will accept an array (second optional parameter), along with a string for the post status name.
Arguments prefixed with an _underscore shouldn’t be used by plugins and themes.
Parameters
$post_statusstringrequired- Name of the post status.
$argsarray|stringoptional- Array or string of post status arguments.
labelbool|stringA descriptive name for the post status marked for translation. Defaults to value of $post_status.label_countarray|falseNooped plural text from _n_noop() to provide the singular and plural forms of the label for counts. Default false which means the$labelargument will be used for both the singular and plural forms of this label.exclude_from_searchboolWhether to exclude posts with this post status from search results. Default is value of $internal._builtinboolWhether the status is built-in. Core-use only.
Default false.publicboolWhether posts of this status should be shown in the front end of the site. Default false.internalboolWhether the status is for internal use only.
Default false.protectedboolWhether posts with this status should be protected.
Default false.privateboolWhether posts with this status should be private.
Default false.publicly_queryableboolWhether posts with this status should be publicly- queryable. Default is value of $public.show_in_admin_all_listboolWhether to include posts in the edit listing for their post type. Default is the opposite value of $internal.show_in_admin_status_listboolShow in the list of statuses with post counts at the top of the edit listings, e.g. All (12) | Published (9) | My Custom Status (2) Default is the opposite value of $internal.date_floatingboolWhether the post has a floating creation date.
Default to false.
Default:
array()
Source
function register_post_status( $post_status, $args = array() ) {
global $wp_post_statuses;
if ( ! is_array( $wp_post_statuses ) ) {
$wp_post_statuses = array();
}
// Args prefixed with an underscore are reserved for internal use.
$defaults = array(
'label' => false,
'label_count' => false,
'exclude_from_search' => null,
'_builtin' => false,
'public' => null,
'internal' => null,
'protected' => null,
'private' => null,
'publicly_queryable' => null,
'show_in_admin_status_list' => null,
'show_in_admin_all_list' => null,
'date_floating' => null,
);
$args = wp_parse_args( $args, $defaults );
$args = (object) $args;
$post_status = sanitize_key( $post_status );
$args->name = $post_status;
// Set various defaults.
if ( null === $args->public && null === $args->internal && null === $args->protected && null === $args->private ) {
$args->internal = true;
}
if ( null === $args->public ) {
$args->public = false;
}
if ( null === $args->private ) {
$args->private = false;
}
if ( null === $args->protected ) {
$args->protected = false;
}
if ( null === $args->internal ) {
$args->internal = false;
}
if ( null === $args->publicly_queryable ) {
$args->publicly_queryable = $args->public;
}
if ( null === $args->exclude_from_search ) {
$args->exclude_from_search = $args->internal;
}
if ( null === $args->show_in_admin_all_list ) {
$args->show_in_admin_all_list = ! $args->internal;
}
if ( null === $args->show_in_admin_status_list ) {
$args->show_in_admin_status_list = ! $args->internal;
}
if ( null === $args->date_floating ) {
$args->date_floating = false;
}
if ( false === $args->label ) {
$args->label = $post_status;
}
if ( false === $args->label_count ) {
// phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralSingular,WordPress.WP.I18n.NonSingularStringLiteralPlural
$args->label_count = _n_noop( $args->label, $args->label );
}
$wp_post_statuses[ $post_status ] = $args;
return $args;
}
Changelog
| Version | Description |
|---|---|
| 3.0.0 | Introduced. |
20is the maximum character length for the$post_statusparameter.wp shellwp> global $wpdb;
wp> $wpdb->get_col_length('wp_posts','post_status')
=> phar:///usr/local/bin/wp/vendor/wp-cli/shell-command/src/WP_CLI/Shell/REPL.php:52:
array(2) {
'type' =>
string(4) "char"
'length' =>
int(20)
}
We’re able to register a post status with a
$post_statusparameter longer than 20 characters, but we’re unable to save/update posts with it. Instead, thewpdb->process_fields()method compares the converted data to the provided data and returnsfalsebecause they’re different.Example
An example of registering a post status called “Unread”:
Something that was not clear in my understanding was the independent nature of Post Statuses in connection with Custom Post Types (CPT). I had always been under the assumption that a specific Post Status had to be linked to a specific post type, but the reality is that post statuses exist separate or independent from any post type or custom post type.
From what I can see, the only place where Post Status is declared is within the code. A list of available post statuses can be generated from the global variable
. These different post_status are not stored as list or array in the options table of database. The only place where post_status is used in the database is in the wp_posts table as the actual `post_status` value.
To load a specific set of post_status values in the post editor screen (for example) is beyond the scope of this comment, but you will want to look into filtering the values for the post_status as is relevant to your needs.
It seems that using the register_post_status function doesn’t add the new post status as an option in the edit post page, or quick edit either, which is disappointing. The issue, and some workarounds, is discussed in more detail here:
https://stackoverflow.com/q/20298346/612253
Hopefully it will help others avoid wasting as much time on the issue as I did!