I'm building functionality to remove posts that have a certain key/value term pair. All fine and dandy, I can run a query like this:

    $posts = get_posts([
        'post_type' => 'any',
        'posts_per_page' => -1,
        'meta_key' => 'my_key',
        'meta_value' => 'my_value',

But I was thinking. Is any really...any in every case? What I mean is, are there any plugins out there that choose to express complex data structures / collections in any other way than a CPT?

WooCoomer's products are a CPT. Easy Digital Downloads are CPT. RevolutionSlider sliders are CPT (combined with shortcodes). It seems the go-to for expressing, really anything in the WordPress ecosystem are CPTs.

But are there edge cases when this doesn't happen and it's a popular plugin?

My question really is if my query has a chance to fail.

  • 1
    Almost certainly. WooCommerce is moving away from CPTs in a future version as well. Those things wouldn't have post meta though, so I'm not sure what you're trying to do here that would also need to apply to custom data. Commented Sep 2, 2018 at 11:37
  • 1
    @JacobPeattie Any sources on that and what exactly they're planning to do?
    – coolpasta
    Commented Sep 3, 2018 at 2:28
  • 1
    woocommerce.wordpress.com/2018/07/17/… Commented Sep 3, 2018 at 2:32
  • 1
    Many, many plugins rely on their own tables/data structures (BuddyPress, NextGEN Gallery, even Automattic's own Jetpack). In general, the more complex the functionality of a plugin, the greater the likelihood of custom data storage becomes. Your query will always "succeed" when looking for data stored as as WordPress post (with the exceptions detailed in Levi Dulstein's answer), but it will of course "fail" in every circumstance where the data you are looking for is not a post.
    – bosco
    Commented Sep 4, 2018 at 17:29
  • @bosco Don't these posts have their own tables, but "pipeline" all that data through a CPT so that a WP_Query works?
    – coolpasta
    Commented Sep 5, 2018 at 5:27

1 Answer 1


Actually if you look closely to the codex, you can see that setting 'post_type' argument to any will by default leave out some post types from the query: https://codex.wordpress.org/Class_Reference/WP_Query#Type_Parameters

'any' - retrieves any type except revisions and types with 'exclude_from_search' set to true.

So you can actually register a post type and make it non-public, there's a bunch of arguments there as you probably know, so you could work with these:

$args = array(
    'public'                => false,
    'show_ui'               => false,
    'show_in_menu'          => false,
    'show_in_admin_bar'     => false,
    'show_in_nav_menus'     => false,
    'show_in_rest'          => false,
    'can_export'            => false,
    'has_archive'           => false,       
    'exclude_from_search'   => true, // this one is important!
    'publicly_queryable'    => false,
register_post_type( 'hidden_post_type', $args );

Taking this under consideration, I'd say that most of the time using CPT is the right way to go, and many popular plugins are doing this, using non-public posts.

You can always look for an extreme solution like building additional tables in database for your plugin, but this isn't a WordPress way to go in my opinion. By using CPT you are getting a bunch of goodies out of the box, such as caching and you don't have to worry about future compatibility.

  • and the parameters can probably be filtered Commented Sep 2, 2018 at 14:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.