2

I'm trying to filter archive_research.php to show only the research with status=current.

In functions.php:

add_action( 'pre_get_posts', 'only_current' );

function only_current( $query ) {
    if ( $query->is_main_query() ) {
        $args = array(
            'post_type' => 'research',
            'tax_query' => array(
                array(
                    'taxonomy' => 'status',
                    'field'    => 'slug',
                    'terms'    => 'current',
                ),
             ),
        );
        $query = new WP_Query( $args );
    }
}

In archive-research.php:

        // theloop
        if ( have_posts() ) : while ( have_posts() ) : the_post();
            // print title etc

Result: research archive displays ALL research.

I have tried many slight alterations of this. For readability I will try to sum them up here without pasting a bunch of redundant code:

  • removing the tax_query .. same result (expected)
  • changing the tax_query to a taxonomy term that does not exist .. same result
  • replacing $query = new WP_Query( $args ) with $query->set('meta_query', $args) or $query->set($args) .. same result
  • replacing have_posts() and the_post() in archive-research to $wp_query->have_posts() and $wp_query->the_post() .. same result
  • adding a call to do_action('only_current') before // theloop .. same result

So the common theme here is that no matter what I do, I get the same result. There must be a very obvious solution that I'm missing, and I would really appreciate it if someone could point it out.

Last bit of debugging info that might be useful:

string(222) "SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts WHERE 1=1 AND wp_posts.post_type = 'research' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') ORDER BY wp_posts.post_date DESC LIMIT 0, 10"

This is the result of calling echo var_dump($wp_query->request) before // theloop

4
  • Am I supposed to make a functions-research.php file or something? I'm new to WordPress so there must be some obvious thing I'm not doing
    – Kristina
    Commented Nov 3, 2015 at 21:22
  • I know that I have published research content with status=current, and I also have other research content with status=completed
    – Kristina
    Commented Nov 3, 2015 at 21:26
  • is status what your custom taxonomy` is called or do you have a custom post_status?
    – Howdy_McGee
    Commented Nov 3, 2015 at 22:59
  • You $query->set( 'tax_query', $taxquery ) - see wordpress.stackexchange.com/a/35263/57034
    – bonger
    Commented Nov 4, 2015 at 2:41

1 Answer 1

2

You're creating a new query, not altering the existing one.

The pre_get_posts codex page has a note explaining that the $query argument is passed by reference and you should alter it directly. There's no need to declare globals or return values. Update your function to be:

add_action( 'pre_get_posts', 'only_current' );
function only_current( $query ) {

    if ( is_admin() ) {
        return;
    }

    if ( ! $query->is_main_query() ) {
        return;
    }

    if ( ! is_post_type_archive( 'research' ) ) {
        return;
    }

    $tax_query = array(
        array(
            'taxonomy' => 'status',
            'field'    => 'slug',
            'terms'    => 'current',
        ),
    );
    $query->set( 'tax_query', $tax_query );
}

The pre_get_posts filter also applies to queries within the admin, so I've added another if statement to check we're on the front end of the site.

I've also added a statement to check we're on the research archive page.

The function above needs to be put in your functions.php file, or a site specific plugin. Placing it in the archive-research.php file will not work because the query will have been run by the time the archive-research.php template is loaded.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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