Question

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.

Was it helpful?

Solution

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

OTHER TIPS

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

Licensed under: CC-BY-SA with attribution
Not affiliated with wordpress.stackexchange
scroll top