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.

I was reading Stephen Harris's excellent answer to this question regarding the use of WP_query(), query_posts() and pre_get_posts.

He says "pre_get_posts is a filter, for altering any query. It is most often used to alter only the 'main query'."

It is possible to use pre_get_posts to filter only a specific secondary query created with WP_Query? eg.

$my_secondary_loop = new WP_Query(...);
if( $my_secondary_loop->have_posts() ):
    while( $my_secondary_loop->have_posts() ): $my_secondary_loop->the_post();
       //The secondary loop
    endwhile;
endif;
wp_reset_postdata();

Any help much appreciated.

share|improve this question
add comment

2 Answers 2

up vote 11 down vote accepted

The simplest way is to add the action right before the query and remove it immediately after.

add_action('pre_get_posts', 'some_function_in_functionsphp');
$my_secondary_loop = new WP_Query(...);
remove_action('pre_get_posts', 'some_function_in_functionsphp');

if( $my_secondary_loop->have_posts() ):
    while( $my_secondary_loop->have_posts() ): $my_secondary_loop->the_post();
       //The secondary loop
    endwhile;
endif;
wp_reset_postdata();

EDIT

Another technique you can use is to set your own query var and check for that in a hook:

// tell WordPress about our new query var
function wpse52480_query_vars( $query_vars ){
    $query_vars[] = 'my_special_query';
    return $query_vars;
}
add_filter( 'query_vars', 'wpse52480_query_vars' );

// check if our query var is set in any query
function wpse52480_pre_get_posts( $query ){
    if( isset( $query->query_vars['my_special_query'] ) )
        // do special stuff

    return $query;
}
add_action( 'pre_get_posts', 'wpse52480_pre_get_posts' );

and in the template:

// set the query var (along with whatever others) to trigger the filter
$args = array(
    'my_special_query' => true
);
$my_secondary_loop = new WP_Query( $args );
share|improve this answer
1  
Very nice bit of info, Milo, thanks :) –  brasofilo May 17 '12 at 22:05
    
Thank you so much Milo. This is really very helpful. I always wondered if it was possible to set your own query var. –  Ben Pearson May 18 '12 at 5:52
    
How can I use this trick for archive page? I don't want to rewrite the whole query again for archive page but want to use this technique. –  Rohit Pande Jul 2 '13 at 9:17
add comment

pre_get_posts fires for every post query:

  • get_posts()
  • new WP_Query()
  • That random recent posts widget your client installed without you knowing.
  • Everything

-- @nacin

With that being said unless you exclude your filter use the conditional: is_main_query() then your filter will fire on your new WP_Query.

If you only want to target your specific new WP_Query then there is no way to do that.

share|improve this answer
    
What about Milo's technique? I've never seen it before... –  brasofilo May 17 '12 at 21:56
    
His technique will work. Ive never used it for pre_get_posts but have for other filters like posts_where –  Chris_O May 17 '12 at 22:02
1  
Cool, something new learned today! –  brasofilo May 17 '12 at 22:05
add comment

Your Answer

 
discard

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

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