Pass arguments to WP_Query using "set" method

grazianodev asked
wp-query
via

I’m altering the main WP_Query to get all posts with a certain meta value using pre_get_posts, like this:

add_action( 'pre_get_posts', 'public_loop' );

public function public_loop( $query ) {
    if ( ! is_admin() && $query->is_main_query() ) { 
        $query->set( 'meta_key', 'deadline' );  
    }
}

Then I’m loading older posts via AJAX, so I need to create a new query which I want to have the same paremeters as the main query I’ve altered. Passing the parameters as arguments works, as expected:

function load_new_posts() {

    $q = new WP_Query( array( 'meta_key' => 'deadline' ) );

    if ( $q->have_posts() ) :
        while ( $q->have_posts() ) : $q->the_post();
            get_template_part( 'views/post/content', get_post_format() );
        endwhile;           
    endif;

}

But passing them using the set method doesn’t:

function load_new_posts() {

    $q = new WP_Query();

    $q->set( 'meta_key', 'deadline' );

    if ( $q->have_posts() ) :
        while ( $q->have_posts() ) : $q->the_post();
            get_template_part( 'views/post/content', get_post_format() );
        endwhile;           
    endif;

}

In the second case, the AJAX call says “This request has no response data available”. However, if I var_dump( $q ) the query looks correct.

I would rather use the set way so I can create a reusable function (since I use it both in pre_get_postsand in the AJAX call).


Answer
via

In the last example (the one that’s not working for you), you’re instantiating an instance of the WP_Query class without passing in an array of query vars. That’s fine, but internally this means the query never actually takes place. You’re calling $q->set( ... ), but that’s only setting a query variable, it doesn’t run the query and retrieve results.

To actually run the query and populate results, do one of two things:

  • Pass query vars to the class constructor.

    $q = new WP_Query( array( 'meta_key' => 'deadline' ) );
    
  • Or, run the query after instantiating.

    $q = new WP_Query();
    $q->query( array( 'meta_key' => 'deadline' ) );
    

What will not work, is this:

$q = new WP_Query();
$q->set( 'meta_key', 'deadline' );
$q->query( array() );

It doesn’t work, because the query() method sets and overrides any existing query variables. Therefore, you can’t use set() in this particular case. Keep in mind, the reason set() works well from the filter in your first example, is because the filter event occurs within the WP_Query class internally. But when you perform a query using the WP_Query class yourself, you must explicitly pass in a set of query vars that establish the query that needs to be run.

Share This
Posted in: