Basically, when I view the All Posts page in Wordpress Admin, I want to filter out all posts from a specific category to now be shown there.

After some searching, I found this hook but it's not working in this instance.

function exclude_category_posts( $query ) {

    if ( $query->is_main_query() && !is_admin() && $query->is_home() ) {
        $query->set( 'cat', '-13, -14, -15, -16' );

add_filter( 'pre_get_posts', 'exclude_category_posts' );

Thanks in advance

  • 1
    Keep in mind that telling the DB to exclude something makes for an expensive/slow query. It would be faster to list every single category except the ones you want, always ask for what you want, not what you don't want – Tom J Nowell Jul 14 '18 at 11:19
  • 1
    Your example is explicity applying when it's not the admin: !is_admin(). – Jacob Peattie Jul 14 '18 at 11:22

If we look at the official documentation for WP_Query:


Show posts associated with certain categories.

  • cat (int) - use category id.
  • category_name (string) - use category slug.
  • category__and (array) - use category id.
  • category__in (array) - use category id.
  • category__not_in (array) - use category id.

The problem is that cat demands a category ID, not an array of values.

We can also see a more appropriate option of category__not_in, and we can use an actual array, not a comma separated list:

$query->set( 'category__not_in', [13,14,15,16] );

Which leads to the other problem, the condition:

if ( $query->is_main_query() && !is_admin() && $query->is_home() ) {

If you want this to run on the admin, why is this part in the check?

!is_admin() && $query->is_home()

It says if it is not the admin, and we're on the homepage, do X. But you want the opposite! Remove the is home bit, and reverse the is_admin by removing the !. This part will require beginner level PHP skills to do.

Finally, asking the database to exclude things, leave stuff out, is expensive, and gets excessively expensive as the amount of content grows.

Additionally, you should never hardcode IDs, all it takes is somebody deleting the category and recreating it, a site migration, etc and it's broken

  • Ya, I want this to be applied only in Posts, All Posts section of WP Admin. Basically filtering posts from category X,Y appearing in that list. – vexx Jul 14 '18 at 12:06
  • I never thought of it as a hardcoding of IDs, didn't knew that filtering out some cat ids from that list will lead to such hassle :( – vexx Jul 14 '18 at 12:08
  • If I have 3 fruit, Apples, Oranges, and Pears, it is faster to ask for all the Apples and Pears, than to ask for all the fruit that are not Oranges. Anything with __not_in or NOT EXISTS or != in a query will make the database construct a temporary table and fill the new table with everything that doesn't match, then it does the query on the new table, then discards it. This means as the amount of content rises, so does the cost of the query, and it doesn't happen linearly, e.g. 2x the content does not mean 2x as slow, it's slower – Tom J Nowell Jul 14 '18 at 14:28
  • Additionally, doing all that lifting takes a strain on the DB server, and consumes memory, meaning your site can handle fewer visitors. On high scale sites with lots of resources, a simple meta query of NOT EXISTS can make the DB servers fall over very quickly. Elastic search and caching help mitigate the problem but it doesn't prevent it. If you can filter them out in PHP great, if you ever need to exclude a single post, just do it in PHP and it's significantly faster than making the DB do it – Tom J Nowell Jul 14 '18 at 14:29
  • Totally understandable, thanks for clearing that up. I'm a novice programmer (at the very beginning), how do you recommend me filtering this in PHP only? Thanks again! – vexx Jul 15 '18 at 11:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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