web-dev-qa-db-fra.com

Utilisation de pré-objets pour réécrire la requête de recherche afin d'afficher les publications de plusieurs taxonomies

Cela semble être simple, mais je suis coincé dessus!

Si un utilisateur recherche "alice", je souhaite lui montrer toutes les publications avec les termes de taxonomie personnalisés de "bob" et "carol", que ces publications contiennent ou non la chaîne "alice".

Je suis en mesure de définir la requête tax_query de sorte qu'elle affiche uniquement les publications avec 'bob' et 'carol', mais je ne peux pas réinitialiser la requête de recherche réelle afin qu'elle affiche toutes les publications, pas seulement les publications avec 'alice 'en eux.

C'est le filtre que j'utilise pour changer le 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;

mais utiliser ceci pour définir la requête de recherche ne fonctionne pas:

$queryvars = array(
        's' => ''
);
$query->set( 'query_vars', $queryvars );
4
Jairus Khan

Cela ne fonctionne pas car vous ne pouvez pas utiliser set pour modifier tous les vars de requête. Le moyen le plus simple de faire l'astuce consiste à définir 's' sur une chaîne vide:

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

});

De cette manière, WordPress considérera toujours la requête comme une recherche. Le modèle search.php sera utilisé pour afficher les résultats. Si vous appelez is_search(), le résultat sera TRUE.

Si vous souhaitez que WordPress ne considère plus la requête comme une recherche, vous devez également désélectionner manuellement $query->query_vars['s'] et définir $query->is_search sur 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;
  }

});

Ce faisant, WordPress ne considérera plus la demande comme une recherche et utilisera index.php comme modèle.

Si vous souhaitez utiliser un autre modèle, par exemple taxonomy.php vous devez utiliser le filtre '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 );
  }

});
7
gmazzap