Hiding Posts in WordPress with a Custom Post Status

Are you looking for a way to hide WordPress posts from both the frontend and the backend?

By default, WordPress displays all post statuses on the backend post list admin screen.  To specifically tell it to exclude a post status, you’ll want to register the post status with the following arguments:

function themeprefix_register_inactive_post_status() {
   register_post_status(
      'prefix-inactive',
      [
         'label' => 'Inactive',
         'public' => false,
         'internal' => true,
         'protected' => true,
         'private' => false,
         'exclude_from_search' => true,
         'publicly_queryable' => false,
         'show_in_admin_all_list' => false,
      ]
   );
}

add_action( 'init', 'themeprefix_register_inactive_post_status' );

I recommend prefixing the post status to avoid potential conflicts — just incase WordPress or a plugin decides to register an inactive post status themselves.

One unintuitive thing is that “private” actually needs to be set to “false” as shown above.

So why would you do this?

In most cases, I’d recommend differentiating types of posts by using a different post type instead of a different post status.

However, in my case, I wanted a way to “soft delete” posts without moving them to the trash.  See, the trash auto-empties after 30 days, and if you move all of the posts to the trash at once, then in 30 days, all of them will be deleted at once, and this could cause some performance issues if you’re dealing with thousands of posts.

So instead I made an inactive post status, and wrote a WP CLI script to set this post status on the content I planned on deleting.  This way I could restore the content if needed, so it’s truly a “soft delete”.  Then, when I want to permanently delete it, I’ll write another custom WP CLI script that permanently deletes them.  This script will sleep at set intervals and also will take other measures to make sure that we don’t cause performance issues!

 

Leave a Reply

Your email address will not be published. Required fields are marked *