Vue d'ensemble
- Espace de noms PHP :
Websource\SearchBar(classes danssrc/, PSR-4, chargeur maisonsrc/Autoloader.php). - Préfixes : options
wsx_searchbar_*, tables{prefix}wsx_searchbar_*, filtres et actionswsx_searchbar_*, handleswsx-searchbar*, classes CSSwssb*. - Sans WooCommerce : la barre ne cherche que dans les pages, le formulaire mène à la recherche native de WordPress (
?s=). - Le serveur n'envoie jamais de HTML dans les suggestions : le navigateur construit le DOM avec
textContent, le surlignage est transmis par positions.
websource-searchbar.php fichier principal (constantes, chargeur, crochets d'activation)
src/Plugin.php branchements WordPress
src/Services.php assemblage des objets
src/Text/ Normalizer, StopWords, SynonymMap, FuzzyMatcher (logique pure)
src/Search/ QueryParser, Ranker, Highlighter, SuggestionEngine (logique pure)
src/Index/ Schema, EntityLoader, DocumentBuilder, IndexWriter, Indexer, IndexHooks, CandidateRepository
src/Presenter/ WooPresenter, ProductHydrator (lien, image, prix, stock)
src/Http/ RestController, RateLimiter
src/Front/ Renderer, Block, Placement
src/Admin/ Settings/ Stats/ Cache/ Support/ Cli/
assets/js/front.js barre (sans jQuery) assets/css/front.css
blocks/search-bar/block.json
Bloc
websource/search-bar — rendu serveur (render_callback), éditeur sans build (assets/js/block-editor.js, wp.element.createElement + ServerSideRender).
| Attribut | Type | Défaut | Rôle |
|---|---|---|---|
size | string | "" | s, m ou l. Vide : réglage de l'extension. |
icon | string | "" | lens, lens-thin ou spark. Vide : réglage de l'extension. |
placeholder | string | "" | Texte d'invite. Vide : réglage de l'extension. |
Supports : align (wide, full), spacing (margin, padding). Le bloc est enveloppé dans <div class="wp-block-websource-search-bar wssb-block">.
<!-- wp:websource/search-bar {"size":"s","icon":"lens-thin","placeholder":"Chercher dans la boutique"} /-->
Code court
[websource_searchbar]
[websource_searchbar size="l" icon="spark" placeholder="Que cherchez-vous ?"]
Mêmes attributs que le bloc.
Fonction de gabarit
<?php echo websource_searchbar(['size' => 'l', 'icon' => 'lens', 'placeholder' => '', 'class' => 'ma-classe']); ?>
websource_searchbar(array $args = []): string renvoie le HTML échappé de la barre et met en file la feuille de style et le script (wsx-searchbar). Les fichiers ne sont chargés que sur les pages où la barre est rendue.
Emplacements automatiques
Réglage placement (filtrable par wsx_searchbar_placement) :
| Valeur | Thème à blocs | Thème classique |
|---|---|---|
header | Filtre render_block_core/template-part : la barre est insérée avant </header> de la partie de gabarit d'en-tête (slugheader, tagNameheader ou zone header). | Action juste après l'en-tête (voir ci-dessous). |
below_header | Même filtre : la barre est ajoutée après la partie de gabarit d'en-tête. | Action juste après l'en-tête. |
native | Filtres get_search_form, get_product_search_form, render_block_core/search, render_block_woocommerce/product-search : la barre remplace le formulaire. | Idem. |
none | Rien. | Rien. |
Thèmes classiques : l'action utilisée est storefront_before_content (Storefront), generate_after_header (GeneratePress), astra_header_after (Astra), kadence_after_header (Kadence), sinon wp_body_open. Elle se change avec le filtre wsx_searchbar_classic_hook.
Avec le réglage hide_native (et un emplacement autre que native), les quatre filtres ci-dessus renvoient une chaîne vide sur le site public.
La barre automatique est enveloppée dans <div class="wssb-band wssb-band--header|wssb-band--below"><div class="wssb-band__inner">…</div></div>.
Routes REST
Espace de noms : wsx-searchbar/v1.
GET /wp-json/wsx-searchbar/v1/suggest
Suggestions pour une saisie. Route publique (permission_callback : limitation de débit par empreinte SHA-256 de l'adresse IP, réglage rate_limit requêtes par fenêtre de 10 secondes).
| Paramètre | Type | Rôle |
|---|---|---|
q | string | Saisie du visiteur (80 caractères et 6 mots pris en compte). Vide : recherches populaires. |
lang | string | Code de langue de l'index. Facultatif : langue courante. |
Requête :
curl "http://127.0.0.1:8304/wp-json/wsx-searchbar/v1/suggest?q=casqette&lang=fr"
Réponse (site de test, en-têtes Cache-Control: private, max-age=30 et Vary: Cookie) :
{
"q": "casqette",
"dm": "casquette",
"p": [
{
"i": 48,
"n": "Casquette Olive",
"u": "http://127.0.0.1:8304/product/casquette-olive/",
"m": "http://127.0.0.1:8304/wp-content/uploads/2026/10/casquette-olive-100x100.jpg",
"pr": "19,90 €",
"st": 1,
"h": [[0, 9]]
},
{
"i": 45,
"n": "Casquette Lagon",
"u": "http://127.0.0.1:8304/product/casquette-lagon/",
"m": "http://127.0.0.1:8304/wp-content/uploads/2026/10/casquette-lagon-100x100.jpg",
"pr": "19,90 €",
"st": 1,
"h": [[0, 9]]
}
],
"c": [
{
"n": "Casquettes",
"u": "http://127.0.0.1:8304/product-category/accessoires/casquettes/",
"c": 2,
"h": [[0, 10]]
}
],
"b": [],
"m": [],
"t": 2,
"tm": 0,
"all": "http://127.0.0.1:8304/?s=casqette&post_type=product"
}
| Clé | Rôle |
|---|---|
q | Saisie normalisée (minuscules, sans accents). |
dm | Correction proposée (« Vous vouliez dire »), vide sinon. |
p, c, b, m | Produits, catégories, marques, pages. |
t, tm | Nombre de produits trouvés dans l'index ; tm vaut 1 si le plafond de 400 candidats est atteint. |
all | Adresse de la page de résultats. Absente si la saisie est trop courte. |
Élément : i identifiant, n libellé, u lien, h zones à surligner [début, longueur], c nombre de produits (catégories, marques). Produit : m image, pr prix affiché, fr vaut 1 si pr est le prix le plus bas d'un produit à variations, op ancien prix, b étiquette de promotion, st stock (0 rupture, 1 en stock, 3 sur commande).
Saisie vide :
curl "http://127.0.0.1:8304/wp-json/wsx-searchbar/v1/suggest?q="
{"q":"","pop":["casquette","sac"]}
Saisie plus courte que le réglage min_chars : mêmes clés, listes vides.
Dépassement de la limite de débit : statut 429, en-tête Retry-After: 10.
{"code":"wsx_searchbar_rate_limited","message":"Trop de requêtes, réessayez dans quelques secondes.","data":{"status":429}}
POST /wp-json/wsx-searchbar/v1/hit
Enregistre un terme dans les statistiques anonymes. Sans effet si le réglage stats est désactivé. Même limitation de débit. Réponse : 204.
| Paramètre | Type | Rôle |
|---|---|---|
q | string | Terme cherché. |
n | integer | Nombre de produits trouvés (0 : recherche sans résultat). Absent : le serveur fait le compte. |
lang | string | Code de langue. Facultatif. |
Les termes contenant @, un lien, ou 9 chiffres et plus sont écartés.
GET ou POST /wp-json/wsx-searchbar/v1/reindex?token=SECRET
Reconstruction complète de l'index, pour une tâche planifiée externe. permission_callback : jeton de l'option wsx_searchbar_cron_token comparé avec hash_equals, ou utilisateur connecté ayant le droit de régler l'extension.
| Statut | Corps |
|---|---|
| 200 | {"ok":true,"products":16,"seconds":0} |
| 403 | {"code":"wsx_searchbar_forbidden","message":"Jeton invalide.","data":{"status":403}} |
| 409 | {"ok":false,"error":"already_running"} |
POST /wp-json/wsx-searchbar/v1/reindex/start et /reindex/step
Réindexation par étapes de la page de réglages. permission_callback : current_user_can() sur le droit de l'extension ; en-tête X-WP-Nonce (nonce wp_rest) requis. start renvoie un curseur {phase, last, generation, done, total, percent}. step reçoit {"cursor": {...}} et renvoie le curseur suivant, jusqu'à phase: "done". Une étape traite 250 produits.
Filtres et actions
| Crochet | Paramètres | Rôle |
|---|---|---|
wsx_searchbar_woocommerce_active (filtre) | bool $active | Force le mode avec ou sans WooCommerce. |
wsx_searchbar_capability (filtre) | string $capability | Droit requis pour les réglages (manage_woocommerce, ou manage_options sans WooCommerce). |
wsx_searchbar_placement (filtre) | string $placement | Emplacement automatique pour la page en cours. |
wsx_searchbar_classic_hook (filtre) | string $hook, string $placement, string $template | Action utilisée par un thème classique. |
wsx_searchbar_html (filtre) | string $html, array $args | HTML de la barre. |
wsx_searchbar_results_url (filtre) | string $url, string $query | Adresse de la page de résultats. |
wsx_searchbar_filter_url (filtre) | string $url, string $filter, int $term_id, string $label, string $lang | Lien d'une suggestion catégorie (category) ou marque (brand), par exemple vers une liste filtrée. Seules les adresses http(s):// ou commençant par / sont acceptées. |
wsx_searchbar_suggestions (filtre) | array $payload, string $query, string $lang | Réponse des suggestions, avant mise en mémoire. |
wsx_searchbar_product_document (filtre) | array $data, int $product_id, string $lang | Données indexées d'un produit : label, reference, ean, brand, categories, keywords, extra_references. |
wsx_searchbar_page_post_types (filtre) | string[] $types | Types de contenus du groupe Pages (page par défaut). |
wsx_searchbar_excluded_page_ids (filtre) | int[] $ids | Pages jamais proposées (Panier, Commande, Mon compte par défaut). |
wsx_searchbar_pages_limit (filtre) | int $limit | Nombre maximal de pages indexées (2000). |
wsx_searchbar_show_prices (filtre) | bool $show | Masque les prix (mode catalogue). |
wsx_searchbar_image_size (filtre) | string $size | Taille d'image des produits (woocommerce_gallery_thumbnail). |
wsx_searchbar_client_ip (filtre) | string $ip | Adresse IP utilisée par la limitation de débit (REMOTE_ADDR par défaut ; à adapter derrière un proxy). |
wsx_searchbar_use_apcu (filtre) | bool $use | Autorise APCu pour la mémoire des réponses (sinon fichiers). |
wsx_searchbar_settings_saved (action) | Settings $settings | Après tout enregistrement des réglages. |
websource_theme_export_sections (filtre) | array $sections | Ajoute la section searchbar (réglages d'affichage et textes) à un paquet de thème Websource. |
websource_theme_import_section (filtre) | mixed $report, array $params | Applique la section searchbar (section, version, data, mode : replace ou merge, dry_run). |
Tâche planifiée : action wsx_searchbar_nightly_reindex (WP-Cron, quotidienne, réglage nightly).
La constante WSX_SEARCHBAR_DISABLE_APCU (à true dans wp-config.php) force la mémoire par fichiers.
Variables CSS
La barre lit les variables du thème Websource (--wst-*), puis les jetons du thème PrestaShop d'origine (--color-*), puis une valeur de repli.
| Variable interne | Lecture | Repli |
|---|---|---|
--wssb-brand | --wssb-c-brand, --wst-brand-600, --color-brand-600 | #0f766e |
--wssb-on | --wst-brand-on, --color-brand-on | #fff |
--wssb-tint | --wst-brand-50, --color-brand-50 | #effaf8 |
--wssb-ink | --wssb-c-text, --wst-ink, --color-ink | #14282b |
--wssb-line | --wst-line, --color-line | #d9e6e4 |
--wssb-bg | --wssb-c-bg, --wst-surface, --color-surface | #fff |
--wssb-r | --wssb-radius, --wst-radius-xl, --radius-xl | 1rem |
| ombre du champ | --wst-card-shadow | none |
Autres variables : --wssb-font-size (taille du texte, 1rem), --wssb-band-width (largeur de la barre automatique, 720px), --wst-gutter (marge latérale de la bande, 16px).
Quand « Reprendre le design de mon thème » est décoché, l'extension pose --wssb-c-brand, --wssb-c-bg, --wssb-c-text et --wssb-radius en style en ligne sur la barre.
.wssb { --wssb-c-brand: #7c3aed; --wssb-radius: 8px; --wssb-band-width: 960px; }
Classes utiles : wssb, wssb--s|m|l, wssb__form, wssb__input, wssb__panel, wssb__row, wssb__row--product, wssb--open (plein écran mobile), wssb--expanded (panneau ouvert).
Accessibilité
Champ : role="combobox", aria-expanded, aria-controls, aria-autocomplete="list", aria-haspopup="listbox", aria-activedescendant. Panneau : role="listbox". Suggestions : role="option", aria-selected. Groupes : role="group" avec aria-labelledby. Zone role="status" (aria-live="polite") pour le nombre de résultats.
Données
Options
| Option | Contenu |
|---|---|
wsx_searchbar_settings | Réglages (tableau validé par Settings::fromStored()). |
wsx_searchbar_cron_token | Jeton secret de la route /reindex. |
wsx_searchbar_index_version | Version de l'index (invalide les mémoires de réponses). |
wsx_searchbar_indexed_at, wsx_searchbar_generation, wsx_searchbar_db_version | États techniques. |
wsx_searchbar_lock_reindex | Verrou pendant une reconstruction. |
Tables
| Table | Contenu |
|---|---|
{prefix}wsx_searchbar_entity | Un élément cherchable par langue (type 1 produit, 2 catégorie, 3 marque, 4 page). |
{prefix}wsx_searchbar_token | Mots pondérés de chaque élément (nom 10, UGS 12, code-barres 15, marque 4, catégorie 3, étiquette 5). |
{prefix}wsx_searchbar_dict | Dictionnaire de correction des fautes. |
{prefix}wsx_searchbar_stat | Statistiques anonymes : terme, nombre de recherches, nombre sans résultat, dernière date. |
Mémoire des réponses : APCu s'il est actif, sinon fichiers dans wp-content/uploads/wsx-searchbar-cache/.
Ce qui est indexé
- Produits (
product) publiés, sans mot de passe, sans le terme de visibilitéexclude-from-search: titre, UGS (_sku), code-barres (_global_unique_id), marques (product_brand), catégories (product_cat), étiquettes (product_tag), UGS et codes-barres des variations. Popularité :total_sales. - Catégories de produits et marques ayant au moins un produit (la catégorie par défaut est écartée).
- Pages publiées sans mot de passe.
Mise à jour de l'index
save_post_product, woocommerce_new_product, woocommerce_update_product, woocommerce_product_set_stock, woocommerce_product_set_stock_status, woocommerce_product_set_visibility, variations (woocommerce_new_product_variation, woocommerce_update_product_variation, woocommerce_variation_set_stock_status), transition_post_status, before_delete_post, set_object_terms, created_/edited_/delete_ de product_cat et product_brand. Les éléments touchés sont notés et l'index est mis à jour une fois, à l'action shutdown.
Fonctions et classes publiques
| Appel | Rôle |
|---|---|
websource_searchbar(array $args = []): string | HTML de la barre. |
Websource\SearchBar\Services::settings(): Settings | Réglages courants (get(), isEnabled(), toArray()). |
Websource\SearchBar\Services::rebuild(): ?int | Reconstruction complète ; null si une reconstruction est déjà en cours. |
Websource\SearchBar\Services::indexer(): Indexer | refreshProducts(int[] $ids), removeProducts(int[] $ids), refreshOthers(), rebuildAll(). |
Websource\SearchBar\Services::engine($settings, $lang)->search($query, Services::searchContext($settings, $lang)) | Recherche sans passer par HTTP. |
Websource\SearchBar\Settings\Package::export(array $settings): array | Section searchbar d'un paquet de thème. |
Websource\SearchBar\Settings\Package::import(array $data, string $mode = 'replace', bool $dryRun = false, int $version = 1): array | Applique une section. |
WP-CLI
wp wsx-searchbar reindex reconstruit l'index
wp wsx-searchbar status contenu de l'index par langue, type de mémoire utilisé
wp wsx-searchbar search "casqette" [--lang=fr] réponse JSON du moteur
wp wsx-searchbar export > searchbar.json
wp wsx-searchbar import searchbar.json [--mode=merge|replace] [--dry-run]
Langues
- Chaînes source en anglais, domaine
websource-searchbar, traductionlanguages/websource-searchbar-fr_FR.poet.mo. - Textes saisis (texte d'invite, recherches suggérées) :
wpml-config.xml(WPML) etpll_register_string()(Polylang, groupe « Websource Search Bar »). Les réglages par langue priment sur ces traductions. - Avec Polylang ou WPML, l'index est tenu par code de langue ; un contenu sans langue est indexé dans toutes les langues.
Limites connues
- Recherche par début de mot (pas de recherche au milieu d'un mot).
- Le nombre affiché par « Voir tous les résultats » vient de l'index et peut différer de la page de résultats de WooCommerce.
- Renommer une catégorie ou une marque ne réindexe pas ses produits : lancer une réindexation.
- Les fichiers JavaScript et CSS sont livrés non minifiés.