What's the best way to alter the query being run on the Posts Edit screen (edit.php)?

The current method I'm using is by passing an argument to the global $wp_query like so:

$wp_query->query( array ('category__in' => array(14,9,2) ) );

However, this doesn't really work as expected once the user pages back and forth, filters, or searches.

2 Answers 2


Few days ago I wrote a quick solution using pre_get_posts filter to hide some pages in admin area.
Maybe you could use it as a good starting point for whatever you'd like to achieve.

if ( is_admin() ) add_filter('pre_get_posts', 'mau_filter_admin_pages');

function mau_filter_admin_pages($query) {
     $query->set('post__not_in', array(1,2,3) );
     // Do not display posts with IDs 1, 2 and 3 in the admin area.
     return $query;

But be careful: pre_get_posts affects almost all post queries on your site. You will have to use some conditions to make it work only where desired. if (is_admin()) was enough for me, but like I said it was quick solution and I haven't tested it properly yet.

Im sure some local wp ninja will correct this if it's too dirty .)

  • You know, I had tried this before, but what I was missing was making sure that it was running on admin_init. I had the filter running through admin_head, which I guess doesn't hold the proper query? Anyways, this does work, so thanks for helping!
    – user2607
    Jan 20, 2011 at 4:32
  • 1
    NOTE: pre_get_posts doesn't run for all queries, it runs for all post queries (or at least, most of them)..
    – t31os
    Jan 20, 2011 at 13:58
  • @t31os Thanks for clarification. I've updated my answer to reflect it.
    – Michal Mau
    Jan 21, 2011 at 10:51

Im sure some local wp ninja will correct this if it's too dirty .)

It's not a bad approach, but i can provide some pointers in improving the function, read on...

Having given many examples in the past on using pre_get_posts it has come to be understanding that pre_get_posts can actually run several times on a given page(at least i'm told and have read as much) and it can mean your callback function will sometimes be called multiple times(when it doesn't need to be doing so).

Rather than using pre_get_posts an alternative is to use parse_query which runs right toward the end of the query object, and only ever runs once, whilst still providing the level of control you need over the query parameters.

As i also pointed in the comments to maugly's answer, pre_get_posts is going to run for pretty much any post queries throughout your site, so it's important that when adding filters/actions to that hook that you use some specificity to ensure the filter does not run when it is not wanted. I say nearly all queries because there is a parameter that can be set for a given post query to bypass filters(suppress_filters if i remember correctly).

WordPress sets various admin variables inside admin.php for each page so you're able(and core code is able) to determine what kind of page is being viewed at any given time, some of them are...


These variables provide enough information about any admin page to make running a filter or action on a select page or pages quite easy.

You can see how these variables are defined here in source.

In the case of the post listing we can expect $pagenow to be edit.php and $typenow will oddly be empty(it only is when the post type is post).

You could conditionally add that filter onto the query using some conditional logic to work out the page, like so...

add_action( 'admin_init', 'possibly_add_exclude_filter' );
function possibly_add_exclude_filter() {
    global $pagenow, $typenow;
    if( 'edit.php' == $pagenow && '' == $typenow ) 
        add_action( 'parse_query', 'set_viewable_posts_by_cat' );
function set_viewable_posts_by_cat() {
      set_query_var('category__in', array(1) );

I hope that's helpful.. :)

  • You guys don't have to worry about this affecting other queries. I've got that covered :) As far as using pre_get_posts or parse_query, from what I could tell, using pre_get_posts was necessary b/c I needed to intercept the query and alter results before they are returned.
    – user2607
    Feb 2, 2011 at 2:51
  • I do have one minor quibble with how pre_get_posts works in WordPress 3.1, which I have noted here: core.trac.wordpress.org/ticket/16320. I may have to look at parse_query again if it works differently in 3.1. If not, it's something I can live with I guess.
    – user2607
    Feb 2, 2011 at 3:02
  • I agree with the devs regarding pre_get_posts behaviour, though i can understand why you'd not want that.
    – t31os
    Feb 2, 2011 at 10:48

Your Answer

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