It’s fairly inefficient to use query_posts
and I often find it’s more trouble than it’s worth. Instead, to set the post type you can just have a hidden input inside the form with name ‘post_type’ and value (in this example) ‘news’. WordPress handles the rest.
Unfortunately it is not so easy with taxonomies (maybe I’ve missed a trick?). However, rather than redo-ing the search with query_posts
, you can just use the pre_get_posts
filter which runs before the database is queried to filter by taxonomy term.
The following assumes your news category has name ‘news-category’ and your post type is ‘news’:
(First remember to remove your query_posts
stuff from the search template – as this just over-rides the default query WordPress performs).
HTML markup
This is the form that displays your search:
<form action="" method="get">
<?php
//Get all (non-empty) terms for taxonomy 'news-category'
$args = array('orderby' => 'name','order' => 'ASC');
$categories = get_terms( 'news-category', $args );
//Display checkbox for each term
foreach ($categories as $category) {
echo '<input type="checkbox" name="my-filter-terms[]" value="'.$category->slug.'">'.esc_html($category->name);
}
?>
<!-- Hidden input to set post type to news-->
<input type="hidden" name="post_type" value="news" />
<!-- Visible input for search term -->
<input type="text" name="s" value="" />
<!-- Submit button -->
<input type="submit" />
</form>
I’ve used my-filter-terms
to store the array of slugs of the checked terms. (It would probably be better to register a custom variable, but I’ll leave that for now. I had hoped to be able to use the default taxonomy query variable but it didn’t seem to work).
Filter the Search
The post type and search term will be automatically handled. The following is to filter by taxonomy term. This goes in your theme’s functions.php:
add_filter('pre_get_posts','my_filter_the_search',10,1);
function my_filter_the_search($query){
//If the query is a search AND taxonomy terms are set, filter by those terms:
if($query->is_search() && isset($_GET['my-filter-terms'])){
//Get array of slugs of checked terms
$terms = (array) $_GET['my-filter-terms'];
//Tax_query array
$tax_query = array(array(
'taxonomy' => 'news-category',
'field' => 'slug',
'terms' => $terms,
'operator' => 'IN',
));
//Tell the query to filter by tax
$query->set('tax_query', $tax_query );
}
return $query;
}
The operator is set to IN
. This means it searches any posts in any one of the checked terms. You could set it to AND
to search posts which are in all the checked terms.