La recherche par défaut de WordPress
La recherche par défaut de WordPress s’effectue sur :
- Tous les types de publication présents dans le site en fonction des extensions installées
- En l’état publiés ou privés
- Dans le titre, le résumé ou le contenu
Elle ne retourne que 10 résultats.
Par exemple, si WooCommerce est installé, elle cherche dans les pages, articles, attachements (médias) et produits.
Pour ceux qui parlent SQL, une requête du mot-clef « cheval » sur un site e-commerce très simple :
À propos de WP_Query
WP_query est une classe centrale de WordPress qui gère les requêtes SQL sur la base de données. Son utilisation est très bien documentée et permet d’effectuer toutes sortes de recherches élaborées en passant des critères sous forme de paramètres lors de son instantiation.
Mais cela n’est pas l’objet précis de cet article. Il est question en effet de modifier à la volée la recherche par défaut effectuée par WordPress lors de l’utilisation de son formulaire de recherche. I va donc plutôt être nécessaire d’utiliser certains des hooks, actions ou filtres, mis à disposition tout au long de son exécution.
Afin de savoir précisément quels hooks utiliser, il est pertinent de parcourir la méthode get_posts()
, qui gère l’exécution de cette requête. Cette méthode débute actuellement ligne 1865 de wp-includes/class-wp-query.php
.
Par la suite, je montre comment modifier ainsi la recherche :
- Restreindre uniquement aux produits WooCommerce,
- Élargir aux catégories de produits, en plus du titre, du résumé et du contenu.
Pour cela, je me préoccupe des deux hooks pre_get_posts
et posts_search
comme détaillé ci-après.
Ajuster les paramètres de recherche
Par paramètres de recherche, j’entends :
- Restreindre la recherche aux produits WooCommerce
- Faire ressortir tous les résultats, et non seulement les 10 premiers
Comme introduit précédemment, le hook utilisé est pre_get_posts( &$query )
. Il prend en paramètre l’instance de WP_Query
utilisée.
Ce hook est une action, qui contrairement à un filtre ne retourne pas un paramètre modifié. Cependant, dans ce contexte, le paramètre est passé par référence, comme le défini le &
. En français, cela signifie que toute modification effectuée sur $query
sera prise en compte par la suite de l’exécution de get_post()
.
Le code :
La petite vérification du début, if ( is_admin() || empty( $search ) )
, permet de ne modifier que les requêtes de recherches effectuées sur la partie front-end du site.
Par acquis de conscience, je vérifie ensuite que la recherche ne s’effectue pas déjà sur les produits, avant de la modifier.
Le coeur de la modification est :
$query->set( 'post_type', array( 'product' ) );
qui force la recherche sur le type de publication product.
$query->set( 'posts_per_page', -1);
qui fait sauter la limite sur le nombre de résultats.
Modifier les critères de recherche
Les critères sont les attributs sur lesquels est effectuée la recherche : titre, résumé, contenu, auxquels je souhaite ajouter la catégorie de produit.
Le hook dédié, qui cette fois est un filtre :
apply_filters_ref_array( 'posts_search', string $search, WP_Query $query )
Il prend deux paramètres :
string $search
: la partie SQL utilisée dans la clauseWHERE
de la requêteWP_Query $query
: l’instance courante deWP_Query
Et alors la il faut se retrousser un peu les manches et réécrire ce morceau de la requête, en prenant soin d’effectuer les bonnes jointures entre les tables de la base de données.
Voilà ce à quoi ressemble cette partie de la requête, dans cet exemple sur le mot-clef « cheval », avant modification :
Puis ce à quoi elle ressemblera après la modification :
Le code pour effectuer cette modification :
Par rapport à la construction par défaut de la requête, je construis $terms_search
et le rajoute dans le AND du paramètre $search
.
Le code intégral
Le code complet de l’exemple regroupé dans une classe Sukellos_Search_Manager
:
La lecture de la méthode WP_Query->get_posts()
montre que la requête de recherche peut être complètement personnalisée de manière programmatique.
En effet, cette méthode comprend l’appel de pas moins de 41 hooks; 2 actions et 39 filtres.