Filter Posts from Tag Archives in WordPress

I’ve been using a commercial WordPress plugin to manage customer testimonials for one of my products. One of the features of the plugin is a tag cloud. The cloud is generated from tags for each testimonial. I’ve used the tags to produce industry specific archives of customer testimonials, which is great for SEO purposes. However, in some cases I’ve created multiple testimonials for the same customer, allowing me to use a short extract or a sentence or two on a landing page rather than having to use the entire testimonial. This resulted in duplicate testimonials from the same customer appearing in the testimonial tag archives. I needed to find a way from stopping this. Here’s how I solved the problem.

First, I added a custom meta field to each duplicate testimonial that I didn’t want to appear in the tag archive. That looks like this:

Defining a Custom Meta Tag

Defining a Custom Meta Field

Given that the testimonials are custom post types I could filter the testimonials from the tag archives by testing for the existence of the new meta field (in this case I called it testimonial-widget-hide-on-tag-archive). The actual value you assign to the new meta field doesn’t matter. We just want the field to be present for the testimonials we do not want to display on the tag archives. To do that I needed to add an action to the pre_get_posts event and add a filter for the new meta key. Here’s the code I added to my functions.php file:

function modify_testimonial_tag_archive_query( $query ) 
{
	if (is_tag() && $query->is_main_query()) 
	{
		$meta_query[] = array(
                    'key'=>'testimonial-widget-hide-on-tag-archive',
                    'compare'=>'NOT EXISTS',
                );	
		$query->set('meta_query',$meta_query);
  }
}
add_action( "pre_get_posts", "modify_testimonial_tag_archive_query" );

Some key things to note here are the use of is_tag() to check that the query is tag based. Then the use of the $query->is_main_query() call to make sure the filter is used for the main query only (the one that works out what posts to display). The $meta_query array is used to put in the key for the new meta field for the posts we created above, and then we’re using the NOT EXISTS comparison. The result of all this is that only posts that DO NOT have the meta value testimonial-widget-hide-on-tag-archive will be displayed on tag based archives.

This entry was posted in php, WordPress on by .

About markn

Mark is the owner and founder of Timesheets MTS Software, an mISV that develops and markets employee timesheet and time clock software. He's also a mechanical engineer, father of four, and a lifelong lover of gadgets.