4

This seems like it should be straightforward, but I'm stuck on it!

If a user searches for 'alice', I would like to show them all posts with the custom taxonomy terms of 'bob' and 'carol', regardless of if those posts contain the string 'alice' in them or not.

I'm able to set the query's tax_query so that it only shows posts with 'bob' and 'carol' as terms, but I can't reset the actual search query so that it is showing all posts, not just posts with 'alice' in them.

This is the filter I'm using to change the tax_query:

if ( !$query->is_search )
    return $query;

$taxquery = array(
    'relation' => 'OR',
    array(
        'taxonomy' => 'people',
        'field' => 'slug',
        'terms' => array( 'bob' ),
    ),
    array(
        'taxonomy' => 'people',
        'field' => 'slug',
        'terms' => array( 'carol' ),
    )
);

$query->set( 'tax_query', $taxquery );
return $query;

but using this to set the search query doesn't work:

$queryvars = array(
        's' => ''
);
$query->set( 'query_vars', $queryvars );
  • Can you please modify your question to include what code you have tried thus far? Thanks! :) – Dan Mar 20 '14 at 16:44
7

It does't work because you can't use set to change all query vars. Simplest way to do the trick is set 's' to an empty string:

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

  if ( ! is_admin() && $query->is_main_query() && $query->is_search() ) {
    $taxquery = array( ... );
    $query->set( 'tax_query', $taxquery );
    $query->set('s', '' );
  }

});

In this way, WordPress will still consider the request a search, so the search.php template will be used to show results and if you call is_search() the result will be TRUE.

If you want that WordPress will not consider anymore the request a search, you need to also manually unset $query->query_vars['s'] and set $query->is_search to false:

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

  if ( ! is_admin() && $query->is_main_query() && $query->is_search() ) {
    $taxquery = array( ... );
    $query->set( 'tax_query', $taxquery );
    $query->set('s', '' );
    unset( $query->query['s'] );
    $query->is_search = FALSE;
  }

});

Doing that, WordPress will not anymore consider the request a search, and will use index.php as template.

If you want to use another template, e.g. taxonomy.php you need to use 'template_include' filter:

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

  if ( ! is_admin() && $query->is_main_query() && $query->is_search() ) {
    $taxquery = array( ... );
    $query->set( 'tax_query', $taxquery );
    $query->set('s', '' );
    unset( $query->query['s'] );
    $query->is_search = FALSE;
    add_filter( 'template_include', function() {
      return locate_template( 'taxonomy.php' )
    }, 0 );
  }

});

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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