vendredi 25 septembre 2026

À propos

Contact

Tips

Améliorer la recherche interne WordPress avec pre_get_posts

La recherche native de WordPress reste limitée par défaut. Quelques ajustements bien ciblés avec pre_get_posts la rendent nettement plus pertinente, sans service tiers.

Par Clément Hadrot • 8 juillet 2021 • 5 min de lecture • Aucun commentaire
Améliorer la recherche interne WordPress avec pre_get_posts

La recherche native de WordPress fonctionne, mais reste sommaire : elle interroge le titre, le contenu et l’extrait de tous les types de contenu publics, sans aucune pondération, et sans tenir compte de la pertinence réelle des résultats. Sur un site avec plusieurs types de contenu (articles, pages, produits, documentation), le champ de recherche renvoie vite un mélange peu exploitable.

Avant d’envisager une solution externe comme Algolia ou une recherche basée sur Elasticsearch, il vaut la peine d’exploiter ce que WordPress propose déjà nativement, via le hook pre_get_posts, qui permet de modifier la requête principale avant son exécution.

Limiter la recherche à certains types de contenu

Le cas le plus courant : exclure certains types de contenu (pages techniques, éléments de menu, réutilisables) des résultats de recherche, pour ne garder que ce qui a du sens pour le visiteur.

add_action( 'pre_get_posts', function( $query ) {
    if ( ! is_admin() && $query->is_search() && $query->is_main_query() ) {
        $query->set( 'post_type', array( 'post', 'page', 'produit' ) );
    }
} );

La double condition ! is_admin() et is_main_query() est essentielle : sans elle, la modification s’appliquerait aussi à la recherche dans l’administration, ou à des requêtes secondaires déclenchées ailleurs sur la page, avec des effets de bord difficiles à diagnostiquer.

Exclure certains contenus explicitement

Un contenu peut avoir besoin d’exister publiquement sans jamais apparaître dans les résultats de recherche (une page de mentions légales, par exemple). Un champ personnalisé couplé à pre_get_posts permet cette exclusion ciblée :

add_action( 'pre_get_posts', function( $query ) {
    if ( ! is_admin() && $query->is_search() && $query->is_main_query() ) {
        $ids_exclus = get_posts( array(
            'post_type'      => 'any',
            'posts_per_page' => -1,
            'fields'         => 'ids',
            'meta_key'       => 'exclure_recherche',
            'meta_value'     => '1',
        ) );
        $query->set( 'post__not_in', $ids_exclus );
    }
} );
L'essentiel à retenir : pre_get_posts modifie la requête principale sans plugin ; Limiter la recherche à certains types de contenu évite le bruit ; Pondérer titre et contenu améliore la pertinence

Rechercher aussi dans les champs personnalisés

Par défaut, WordPress ne recherche que dans le titre, le contenu et l’extrait. Pour inclure un champ personnalisé (une référence produit, par exemple), il faut intervenir directement sur la clause SQL via les filtres posts_join et posts_where :

add_filter( 'posts_join', function( $join, $query ) {
    global $wpdb;
    if ( $query->is_search() && $query->is_main_query() ) {
        $join .= " LEFT JOIN {$wpdb->postmeta} AS pm_ref ON ({$wpdb->posts}.ID = pm_ref.post_id AND pm_ref.meta_key = 'reference')";
    }
    return $join;
}, 10, 2 );

add_filter( 'posts_where', function( $where, $query ) {
    global $wpdb;
    if ( $query->is_search() && $query->is_main_query() ) {
        $search_term = $wpdb->esc_like( $query->get( 's' ) );
        $where = preg_replace(
            "/\(\s*{$wpdb->posts}.post_title\s+LIKE\s*(\'[^\']+\')\s*\)/",
            "({$wpdb->posts}.post_title LIKE $1) OR (pm_ref.meta_value LIKE '%{$search_term}%')",
            $where
        );
    }
    return $where;
}, 10, 2 );

Cette manipulation directe du SQL reste délicate et doit être testée avec attention : une expression régulière mal calée peut casser la recherche native pour d’autres requêtes.

Trier par pertinence plutôt que par date

WordPress trie les résultats de recherche par date de publication, ce qui n’a souvent aucun rapport avec la pertinence réelle. Un tri approximatif par pertinence, basé sur la présence du terme dans le titre, peut s’implémenter via posts_orderby :

add_filter( 'posts_orderby', function( $orderby, $query ) {
    global $wpdb;
    if ( $query->is_search() && $query->is_main_query() ) {
        $search_term = esc_sql( $query->get( 's' ) );
        $orderby = "(CASE WHEN {$wpdb->posts}.post_title LIKE '%{$search_term}%' THEN 0 ELSE 1 END), " . $orderby;
    }
    return $orderby;
}, 10, 2 );

Ce tri place en tête les résultats dont le titre contient exactement le terme recherché, avant les résultats qui ne le contiennent que dans le corps du contenu.

Limiter la longueur minimale de recherche

Un terme d’un ou deux caractères déclenche souvent une requête très large et peu utile. Une vérification simple évite ce cas :

add_action( 'pre_get_posts', function( $query ) {
    if ( $query->is_search() && $query->is_main_query() ) {
        $terme = $query->get( 's' );
        if ( mb_strlen( trim( $terme ) ) < 3 ) {
            $query->set( 's', '' );
            $query->set( 'post__in', array( 0 ) );
        }
    }
} );

Quand passer à une solution externe

  • Le volume de contenu dépasse plusieurs dizaines de milliers d’entrées, avec un impact mesurable sur le temps de réponse
  • Le besoin porte sur une vraie pertinence sémantique (fautes de frappe, synonymes, recherche à facettes)
  • Les visiteurs utilisent la recherche comme point d’entrée principal du site, ce qui justifie l’investissement

Avant de payer pour une recherche externe, mieux vaut vérifier ce que pre_get_posts permet déjà de résoudre : sur la majorité des sites de contenu, cela suffit largement.

En résumé

pre_get_posts permet d’améliorer sensiblement la recherche native de WordPress sans dépendance externe : filtrage par type de contenu, exclusions ciblées, tri par pertinence approximative. Les manipulations SQL plus poussées (recherche dans les champs personnalisés) demandent davantage de rigueur, mais restent accessibles. Une solution comme Elasticsearch ne se justifie vraiment qu’à partir d’un volume de contenu conséquent ou d’un besoin de pertinence sémantique fine.

Partager :

À propos de l'auteur

Clément Hadrot

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi