Créer un champ de recherche de fonctionnalités ultra-performant pour votre extension WordPress
Si votre extension grandi bien et a gagné des dizaines de réglages ces dernières années, il y a de fortes chances que les personnes utilisant votre produit puissent se perdre un peu. On ne veut pas qu’elles passent 10 minutes à fouiller dans vos onglets. L’objectif est clair : leur offrir une recherche instantanée, intelligente et qui pardonne les fautes de frappe en bonus.
Nous allons voir ensemble comment cloner le système de recherche mis en place dans SecuPress v2.6 sortie le 16 Janvier 2026. C’est propre, c’est rapide, et c’est surtout indispensable pour l’UX d’un plugin « pro ». Sinon vous ne seriez pas là, n’est-ce pas ?
Étape 1 : Le Markup — Simple, accessible et extensible
On ne balance pas un <input> au pif en haut de page en espérant que quiconque s’en sorte. Pour un moteur de recherche digne de ce nom, il faut respecter 3 règles fondamentales et je dis ça alors que je ne suis ni dev front, ni pro en UX, c’est juste ma logique, n’hésitez pas à me donner votre avis là-dessus, si on peut encore faire mieux ça serait top.
- L’accessibilité : Le
placeholderne remplace jamais un label. Utilisez impérativementlabel.screen-reader-text. Les lecteurs d’écran vous remercieront. - Feedback de chargement : Un loader est obligatoire. Il doit être masqué par défaut (un petit
.hiddenoudisplay: none) et activé seulement quand la requête tourne. - Conteneur de résultats : Prévoyez une liste
<ul>dédiée pour injecter vos résultats dynamiquement.
Enveloppez ensuite votre bloc dans une classe hide-if-no-js. Si le JavaScript est HS ou désactivé, le champ disparaît proprement au lieu de rester là, inutile et frustrant. C’est ça, le progressive enhancement. Et non on ne va pas gérer ce champ en NO-JS.
Étape 2 : Chargement et Sécurité — Nonce et versioning
Pour que votre moteur ne devienne pas une passoire, on injecte les données proprement via PHP. Voici ma règle d’or pour votre wp_enqueue_scripts :
- Ciblez vos écrans : N’allez pas charger ce script sur toutes les pages de l’admin. Utilisez
$hook_suffixpour limiter l’exécution uniquement à la page de réglages de votre extension, personne n’aime quand tout est inclus partout je le sais… - Passez les bons paramètres : Utilisez
wp_localize_scriptpour transmettre ces 2 éléments :- Le nonce pour valider l’action AJAX.
- La version de votre plugin (votre constante
VERSION).
Pourquoi la version ? C’est la clé de votre cache ! Ha oui car on y met du cache !! Si vous mettez à jour votre plugin mais que le localStorage garde l’ancienne structure des menus, tout va casser. Si la version change, on vide le cache. Simple, net, efficace.
Étape 3 : Le JavaScript — Performance et cache intelligent
C’est ici que la magie opère. Votre handler d’input doit être une machine huilée et optimisée :
- Le filtre des 2 caractères : En dessous de 2 caractères, on ignore la requête. Chercher « a » ou « s » n’a aucun sens et sature le serveur pour rien.
- Debounce (300ms) : On ne lance pas une requête à chaque touche pressée. On attend que l’utilisateur fasse une micro-pause. 300ms, c’est le « sweet spot » comme dises les… heu je sais pas.
- L’AbortController : Si l’utilisateur tape vite, plusieurs requêtes peuvent se chevaucher. Utilisez
AbortController(ouxhr.abort()) pour couper les jambes aux requêtes obsolètes. Ça évite l’effet de « yoyo » sur l’affichage des résultats, vous détestez ça aussi non ? - LocalStorage & LRU : On stocke les 10 (à vous de voir) dernières recherches dans le navigateur (structure
{version, order, results}). Si l’utilisateur tape un mot déjà cherché, le résultat est instantané et ça, ça fait super plaisir. Surtout qu’il y a de fortes chances qu’on cherche souvent la même chose ! - Cache du « zéro résultat » : Si une recherche ne donne rien, on le met aussi en cache. Si l’utilisateur insiste, on n’interroge pas le serveur pour lui redire la même chose.
Étape 4 : Le Serveur (PHP) — Algorithme de scoring et tri
Côté serveur, notre action wp_ajax_secupress_search doit être plus maligne qu’un simple strpos(). On veut de la pertinence.
- Sécurité systématique : Vérifiez les
capabilitydu compte qui lance la requête et son nonce. Pas de bras, pas de chocolat. - Parcours des sous-modules : Ne vous limitez pas à une liste statique. Votre boucle doit parcourir dynamiquement les fonctionnalités et sous-modules de votre extension pour être toujours à jour.
- L’algorithme de scoring :
- Match exact : Score maximum.
- Préfixe : « fi » matchera mieux « Firewall » que « Wifi ». C’est plus naturel.
- Levenshtein : On calcule la distance entre les mots pour tolérer les fautes de frappe (ex: « firwal » trouvera tout de même « firewall »).
- Le seuil de bruit : On ne renvoie rien en dessous d’un seuil de 0.7. Si c’est trop éloigné, c’est que ça n’a rien à voir. On veut de la qualité, pas de la quantité.
Renvoyez enfin un payload JSON minimal (titre et URL). Plus c’est léger, plus ça va vite. C’est tout !
Et la fonction levenshtein (elle existe dans PHP ! La mienne fait le calcul en plus) :
Quelques exemples
Checklist « Copiable » pour votre extension
Vérifiez que vous avez tout coché avant de pousser en prod :
Interface & Performance UI
- [ ] Classe
hide-if-no-jsprésente sur le wrapper. - [ ] Label accessible via
label.screen-reader-text. - [ ] Loader de chargement masqué par défaut.
- [ ] Conteneur
<ul>prêt pour l’injection.
Logique JavaScript (Front-end)
- [ ] Requêtes ignorées si moins de 2 caractères.
- [ ] Debounce calé à 300ms.
- [ ] Gestion de l’annulation (
AbortController). - [ ] Cache LocalStorage persisté (limite LRU de 10 entrées).
- [ ] Invalidation du cache si la version du plugin change.
Logique PHP (Back-end)
- [ ] Vérification stricte des droits et du nonce.
- [ ] Algorithme de scoring (Exact > Préfixe > Levenshtein).
- [ ] Seuil de pertinence fixé à 0.7 minimum.
- [ ] Payload JSON compact (uniquement
titleeturl).
Une recherche fluide, ce n’est pas un luxe, en implémentant ce système, vous augmentez radicalement la rétention de vos utilisateurs.
Vous aimez ? Partagez !
Partager la publication « Créer un champ de recherche de fonctionnalités ultra-performant pour votre extension WordPress »








Réagir à cet article