Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

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.

share|improve this question
add comment

2 Answers 2

up vote 2 down vote accepted

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 .)

share|improve this answer
    
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 '11 at 4:32
    
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 '11 at 13:58
    
@t31os Thanks for clarification. I've updated my answer to reflect it. –  Michal Mau Jan 21 '11 at 10:51
add comment

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...

$pagenow
$parent_file
$plugin_page
$submenu_file
$typenow

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.
http://core.trac.wordpress.org/browser/tags/3.0.4/wp-admin/admin.php

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) );
      return;
}

I hope that's helpful.. :)

share|improve this answer
    
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 '11 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 '11 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 '11 at 10:48
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.