Executing Queries in tag.php

I’m probably being dense, but I can’t seem to figure out what the issue here is.

The site I’m developing uses a custom loop, with a query that excludes any posts ticked as archived.

The reason I want to edit the tag.php template is to output custom meta to the front end, and tweak the appearance of all posts on the archive pages.

It works perfectly for the majority of the site, but on tag.php it causes to tag cloud to break, making any and every tag clicked bring up the full post list.

When I remove the query the tag cloud works fine, but archived posts are still displayed and aren’t laid out the way they need to be.

The query code I’m using is:

// The Queries
   $args = array(
      'post_type' => array('post', 'report', 'analysis', 'guest-blog'),
      'order'     => 'DESC',
      'meta_query'     => array(
            array(
               'key'     => 'epi_pubarchive',
               'value'   => 1,
               'compare' => '!=',
           )
      )
   );

 $the_query = new WP_Query( $args );

The meta key, epi_pubarchive, is a checkbox created using Meta Box, essentially checking if the box is ticked or not.

I’ve tried removing the meta_query and trying it with the basic post_type and order args, but that won’t work either.

Anyone know what the issue with the tag template and queries is?

Is there a better way to achieve the desired result?

1 Answer
1

That’s because the main query is being discarded and replaced with your custom query. You’ve not told your custom query to look for that tag, so why would it? You might also notice your pagination is broken for the same reason, you’ve not told the new query which page you’re on, so why would it pull the right page?

What’s more, that main query is expensive! Why are you throwing it away! Why not modify it instead?

Imagine you sent your friend to get you a latte every morning, and every day after a 20 minute trip, you threw the coffee in the bin and said “I’m lactose intolerant, give me a hot chocolate instead”. They then go off for another 20 minute trip to fetch the hot chocolate, leaving your friend annoyed, and you waiting 40 minutes instead of 20. Wouldn’t it be easier if you tapped them on the shoulder before they left and said “Hey I changed my mind, I want a hot chocolate”?

Use the pre_get_posts filter to change the options on the main query before it happens, e.g. here’s how you can change how many posts are per page:

add_filter( 'pre_get_posts', function( \WP_Query $query ) {
    if ( $query->is_tag() && $query->is_main_query() ) {
        $query->set( 'posts_per_page', 5 );
    }
} );

You can use $query->set to change other options too, and you should do this to set your post types and taxonomy exclusion.

A final note on data storage and performance

You should never look for everything but XYZ, you want to say what you’re looking for, not what you’re not looking for. It’s slower, and doesn’t scale. Sometimes it’s actually faster to get everything then manually remove it in PHP!

So instead of adding posts to an archived term, consider using an unread/unarchived term, and looking for those instead?

Leave a Comment