Использование pre_get_posts для переопределения поискового запроса с отображением записей из нескольких таксономий

20 мар. 2014 г., 18:27:27
Просмотры: 19K
Голосов: 7

Казалось бы, это должно быть просто, но я застрял на этом!

Если пользователь ищет 'alice', я хочу показать ему все записи с терминами пользовательских таксономий 'bob' и 'carol', независимо от того, содержат ли эти записи строку 'alice' или нет.

Я могу установить tax_query в запросе, чтобы показывались только записи с терминами 'bob' и 'carol', но не могу сбросить сам поисковый запрос, чтобы показывались все записи, а не только те, которые содержат 'alice'.

Вот фильтр, который я использую для изменения 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;

Но попытка установить поисковый запрос таким образом не работает:

$queryvars = array(
        's' => ''
);
$query->set( 'query_vars', $queryvars );
1
Комментарии

Не могли бы вы изменить ваш вопрос, включив в него код, который вы уже пробовали? Спасибо! :)

Dan Dan
20 мар. 2014 г. 18:44:30
Все ответы на вопрос 1
0
12

Это не работает, потому что нельзя использовать set для изменения всех параметров запроса. Самый простой способ — установить параметр 's' в пустую строку:

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', '' );
  }

});

Таким образом, WordPress по-прежнему будет считать запрос поисковым, поэтому для отображения результатов будет использоваться шаблон search.php, а при вызове is_search() будет возвращаться TRUE.

Если нужно, чтобы WordPress больше не считал запрос поисковым, необходимо также вручную удалить $query->query_vars['s'] и установить $query->is_search в 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;
  }

});

После этого WordPress больше не будет считать запрос поисковым и будет использовать шаблон index.php.

Если нужно использовать другой шаблон, например taxonomy.php, следует применить фильтр 'template_include':

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 );
  }

});
21 мар. 2014 г. 03:15:17