web-dev-qa-db-fra.com

Exclure un terme spécifique de la recherche

Il est possible de rechercher des publications avec un terme spécifique en ajoutant l'URL avec:

?&term=abc

Est-il possible de faire le contraire et de chercher en excluant un terme spécifique? Quelque chose comme:

?&term=NOTabc
6
Rob

L'explication de base

  1. Vous avez une balise de modèle appelée is_search() pour déterminer si vous êtes sur une page de recherche ou non.
  2. Ceci appelle ensuite get_search_template() qui est fondamentalement une fonction wrapper pour get_query_template('search').
  3. Lorsque vous examinez la dernière fonction, vous constaterez qu’elle exécute essentiellement locate_template(), qui vérifie l’existence du fichier, puis effectue une load_template().
  4. Là, votre $wp_query->query_vars sera vérifié et le $_template_file sera extrait et chargé.

Une note avant sur la requête var…

WordPress utilise la requête var s pour enregistrer le terme recherché dans sa requête. Si vous exécutez une chaîne de requête personnalisée, vous devez modifier le filtre get_search_query comme suit:

/**
 * Modify search query var
 * Doesn't need to be wrapped into esc_attr(), as it's already done by core
 * 
 * @param string $s | The query var to save the search in
 * @return string $s
 */
function change_search_query_var( $s )
{
    $s = 'your_custom_query_var';

    return $s;
}
add_filter( 'get_search_query', 'change_search_query_var', 20, 1 );

Quelques solutions

Nous avons maintenant différentes solutions possibles:

La solution facile

Fonctionne dans le modèle et convient mieux pour exclure les termes de taxonomie.

A) Obtenir toutes les publications dans la boucle du modèle, vérifiez chaque publication de la boucle pour chaque terme (taxonomie) 1) et ensuite exclure/ne pas le montrer.

Dans votre boucle dans votre fichier de modèle search.php:

if ( have_posts() ) {
    while ( have_posts() ) {
        the_post();

        global $post;
        // Skip if the post has the term attached
        if ( is_object_in_taxonomy( 
            $post->ID,
            'YOUR_TAXONOMY',
            array( 'TERM A', 'TERM B', '...' ) 
        )
        continue;
    } 
}

Ceci est juste un exemple de la boucle.

La solution sophistiquée

S'exécute avant d'exécuter la requête principale et convient mieux à l'exclusion des termes en général.

B.1) Filtrez le terme en dehors de la requête de modèle de recherche.

Dans l'exemple suivant, j'utilise le filtre posts_clauses pour vous montrer que vous pouvez en modifier encore plus avec un seul filtre (créez un var_dump du tableau $pieces pour plus d'informations). Vous pouvez également utiliser le filtre posts_where, qui s'exécute avant le filtre de clauses.

// In your functions.php file
/**
 * Modify the search query where clause
 * Like escapes the term for security reasons
 * 
 * @param array $pieces | The array of post clauses: Where, Group by, etc.
 * @return array $pieces
 */
add_filter( 'posts_clauses', 'alter_search_query', 10, 2 );
function alter_search_query( $pieces, $query )
{
    // Target all search queries in the front-end:
    if( is_admin() || ! $query->is_search() ) return $pieces;

    global $wpdb;
    $term = $wpdb->esc_like( 'YOUR_TERM' );

    $pieces['where'] .= $wpdb->prepare( 
        " AND   {$wpdb->posts}.post_title NOT LIKE '%s'",
        "%{$term}%" 
    );

    return $pieces;
}

B.2) Filtrez le terme en dehors de la requête de modèle de recherche _de manière plus performante et plus spécifique.

Dans l'exemple suivant, j'utilise le filtre posts_search pour vous montrer comment modifier la clause where uniquement pour la requête de recherche. C'est à peu près la même chose que le filtre posts_where.

// In your functions.php file
/**
 * Modify the search query where clause
 * Like escapes the term for security reasons
 * 
 * @param array $pieces | The array of post clauses: Where, Group by, etc.
 * @return array $pieces
 */
add_filter( 'posts_search', 'alter_search_where', 10, 2 );
function alter_search_where( $search_term, $query )
{
    // Target all search queries in the front-end:
    if( is_admin() || ! $query->is_search() ) return $search_term;

    global $wpdb;
    $term = $wpdb->esc_like( 'YOUR_TERM' );

    $search_term .= $wpdb->prepare( 
        " AND   {$wpdb->posts}.post_title NOT LIKE '%s'",
        "%{$term}%" 
    );

    return $search_term;
}

Notes de bas de page:

1) Vous n’avez pas précisé s’il s’agissait d’un recherche ou d’un taxonomie terme.

11
kaiser

Réponse très détaillée et approfondie que @kaiser a publiée ci-dessus. Je voulais utiliser la première méthode, mais il semble que la fonction de la première méthode utilisée dans Current wp 4.7 ne fonctionne pas.

Nous devons utiliser une autre fonction que Wordpress a appelée has_term au lieu de is_object_in_taxonomy pour rechercher des termes spécifiques dans la taxonomie attribuée à la publication en cours.

Voici le code final qui a fonctionné pour moi en utilisant la fonction has_term dans votre search.php. Tout modèle de page personnalisé que vous utilisez pour les résultats de recherche. Dans mon cas, il ignore les propriétés de la recherche si leur statut est VENDU ou LOUÉ:

if ( have_posts() ) : while ( have_posts() ) : the_post();

//Skip the post if property taxonomy rl_status is sold or rented: 
    if(has_term(array( 'sold', 'rented' ), 'rl_status', get_the_ID() ){

        continue;
            }
0
Mohsin