Accueil

Référence développeur · WordPress

Websource Faceted Search pour WordPress — référence développeur

Blocs, codes courts, format d'URL, filtres et actions, routes REST, variables CSS et classes publiques de l'extension de filtres à facettes.

Version 1.2.0 · WordPress 6.4+, WooCommerce 8+ (obligatoire) · Mis à jour le 09/10/2026

Guide utilisateur

Cette extension existe aussi pour : PrestaShop

Architecture

websource-facetedsearch.php   fichier principal : constantes, chargeur PSR-4, compatibilité HPOS, amorçage
src/Plugin.php                amorçage (inerte sans WooCommerce), activation, désactivation
src/Settings.php              réglages (option wsx_facetedsearch_settings)
src/Templates.php             modèles de filtres (option wsx_facetedsearch_templates), types, styles, résolution
src/Context.php               page en cours : type, terme, recherche, URL de base
src/Url.php                   format d'URL des filtres
src/Engine.php                sélection, conditions SQL, valeurs et compteurs
src/Renderer.php              rendu HTML du bloc et des pastilles
src/Frontend.php              requête principale, emplacement, blocs, codes courts, SEO
src/Cache.php, Tasks.php      mémoire, invalidation, préparation planifiée
src/Rest.php, Admin.php       API REST, écran de réglages
src/Swatches.php              couleur et texture des valeurs d'attributs
src/ThemePackage.php          export / import par paquet de thème

Espace de noms : Websource\FacetedSearch. Préfixes : options wsx_facetedsearch_*, transients wsx_fs_*, classes CSS wsfs-*.

Sources de données : wc_product_meta_lookup (prix, stock, promotion, note), wc_product_attributes_lookup (attributs, stock par variation ; repli sur term_relationships si la table est absente, vide ou en reconstruction), term_relationships (catégories, marques, étiquettes, visibilité).

Blocs

BlocNomAttributsRendu
Filtres produits (Websource)websource/facetsaucun (supports : align, spacing)Bloc de filtres de la liste en cours. Vide hors liste de produits. Une seule instance par page.
Filtres actifs (Websource)websource/active-filtersaucun (supports : align, spacing)Pastilles des filtres appliqués.

Les deux blocs sont rendus côté serveur (render_callback), déclarés par blocks/*/block.json, sans étape de build.

Codes courts

Code courtÉquivalentAttributs
[websource_facets]bloc websource/facetsaucun
[websource_active_filters]bloc websource/active-filtersaucun

Emplacement automatique

Quand le réglage auto_place est actif :

  • thèmes classiques : actions woocommerce_before_shop_loop (priorité 1) et woocommerce_after_shop_loop (priorité 999), ainsi que woocommerce_no_products_found ;
  • thèmes blocs : filtres render_block_woocommerce/product-collection et render_block_core/query (priorité 1000), pour les blocs qui héritent de la requête de la page.

Structure produite :

<div class="wsfs-layout wsfs-layout--d-sidebar wsfs-layout--m-drawer">
  <aside class="wsfs-aside"><div id="wsfs-root" class="wsfs" data-wsfs>…</div></aside>
  <div class="wsfs-main" data-wsfs-main><div class="wsfs-active" data-wsfs-active>…</div> …liste…</div>
</div>

Format d'URL

Un seul paramètre, wsf par défaut :

/boutique/?wsf=marques:nordik/couleur:bleu,vert/prix:10-50
  • / sépare les filtres, : suit le nom du filtre, , sépare les valeurs.
  • Nom du filtre : titre du filtre passé par sanitize_title (marques, couleur, prix…). La clé technique (brand, attr_couleur, price…) est aussi acceptée.
  • Valeurs : identifiant (slug) du terme ; pour les options, titre de l'option (en-stock, en-promotion…) ou clé (in_stock, promo…) ; pour le prix, min-max dans la devise affichée.
  • Les filtres sont toujours écrits dans l'ordre du modèle : une sélection = une seule URL.
  • orderby, s et post_type sont conservés. La pagination revient à la page 1 quand un filtre change.
  • Sans JavaScript, le formulaire de prix envoie wsfs[prix][min] et wsfs[prix][max] ; le serveur redirige (302) vers l'URL propre.

SEO des pages filtrées : noindex, follow (filtre wp_robots, en-tête X-Robots-Tag), <link rel="canonical"> vers la liste sans filtre. Si tous les filtres actifs sont « indexables » et que leur nombre ne dépasse pas max_indexable_filters, la page reste indexable avec un canonical vers elle-même. Yoast SEO et Rank Math sont pris en compte (wpseo_canonical, wpseo_robots, rank_math/frontend/canonical).

Hooks et filtres

Filtres

FiltreParamètresRôle
wsx_facetedsearch_query_varstring $name (wsf)Nom du paramètre d'URL ([a-z][a-z0-9_]*).
wsx_facetedsearch_active_filtersarray $filters, array $template, string $pageTypeFiltres actifs d'une page, indexés par clé, dans l'ordre.
wsx_facetedsearch_scope_wherestring $where, Context $contextClause WHERE du périmètre (alias p = articles, l = wc_product_meta_lookup).
wsx_facetedsearch_price_factorfloat $factorRapport entre le prix affiché et le prix stocké (TVA).
wsx_facetedsearch_is_color_attributebool $isColor, string $taxonomyIndique si un attribut est une couleur (style par défaut « pastilles »).
wsx_facetedsearch_swatcharray $swatch, int $termId, string $slugCouleur et texture d'une valeur : ['color' => '#rrggbb', 'texture' => 'https://…'].
wsx_facetedsearch_indexablebool $indexable, Engine $engineDécision d'indexation d'une page filtrée.
wsx_facetedsearch_facets_htmlstring $html, Engine $engineHTML final du bloc de filtres.
wsx_facetedsearch_filter_urlstring $url, array $argsURL filtrée demandée par une autre extension (voir ci-dessous).
websource_theme_exportarray $sections, array $contextAjoute la section facetedsearch (version 1) à un paquet de thème.
websource_theme_import?array $report, string $key, array $section, array $contextImporte la section facetedsearch (mode : replace ou merge, dry_run).

Lien filtré pour une barre de recherche :

$url = apply_filters('wsx_facetedsearch_filter_url', $lienNatif, ['filter' => 'brand', 'id' => 17]);
// http://exemple.test/boutique/?wsf=marques:nordik   (ou $lienNatif si le filtre Marques est inactif)

filter vaut brand (ou manufacturer) ou category ; pour une catégorie, la réponse est la page de la catégorie.

Retirer un filtre sur une catégorie précise :

add_filter('wsx_facetedsearch_active_filters', function (array $filters, array $template, string $pageType) {
    if (is_product_category('papeterie')) {
        unset($filters['attr_taille']);
    }
    return $filters;
}, 10, 3);

Évènement JavaScript

Après chaque mise à jour sans rechargement, document reçoit wsfs:updated :

document.addEventListener('wsfs:updated', function (event) {
  console.log(event.detail.url, event.detail.total);
});

Invalidation

La mémoire est invalidée (numéro de version incrémenté) sur : woocommerce_new_product, woocommerce_update_product, woocommerce_update_product_variation, woocommerce_product_set_stock, woocommerce_variation_set_stock, woocommerce_product_set_stock_status, woocommerce_variation_set_stock_status, woocommerce_delete_product, woocommerce_trash_product, woocommerce_attribute_added|updated|deleted, wc_after_products_starting_sales, wc_after_products_ending_sales, transition_post_status (produits), created_term, edited_term, delete_term (taxonomies de produits), comment_post (avis), wp_set_comment_status.

Depuis votre code : \Websource\FacetedSearch\Cache::bump();

Tâche planifiée

Évènement WP-Cron wsx_facetedsearch_warmup (récurrence wsx_fs_warmup, réglage warmup_minutes) : calcule les filtres sans sélection de la boutique et des warmup_top catégories les plus fournies.

Routes REST

Espace de noms : websource-facetedsearch/v1.

MéthodeCheminAccèsRôle
GET/facetspublicFiltres, compteurs et total d'une liste.
GET/previewmanage_woocommerceHTML du bloc de filtres (aperçu de l'administration).
GET/statusmanage_woocommerceÉtat des tables de recherche, de la mémoire et de la préparation.
POST/cache/flushmanage_woocommerceVide la mémoire.
POST/warmupmanage_woocommerceLance la préparation maintenant.
POST/reindexmanage_woocommerceDemande à WooCommerce de reconstruire ses tables de recherche.
GET/templates/recommendedmanage_woocommerceModèle conseillé calculé d'après le catalogue.

Paramètres de /facets et /preview :

ParamètreTypeDéfautRôle
typeshop, category, brand, tag, searchshopType de page.
termentier0Identifiant du terme (catégorie, marque, étiquette).
searchtextevideMots recherchés.
filterstextevideSélection, au format du paramètre d'URL.

Exemple :

GET /wp-json/websource-facetedsearch/v1/facets?type=category&term=28&filters=taille:m

Réponse (extrait : un seul filtre, deux valeurs) :

{
  "total": 5,
  "url": "http://127.0.0.1:8306/product-category/vetements/?wsf=taille:m",
  "filtered": true,
  "active": [
    {
      "facet": "Taille",
      "label": "M",
      "url": "http://127.0.0.1:8306/product-category/vetements/"
    }
  ],
  "facets": [
    {
      "key": "attr_taille",
      "type": "attribute",
      "title": "Taille",
      "url_key": "taille",
      "widget": "checkbox",
      "multiple": true,
      "collapsed": false,
      "show_limit": 10,
      "searchable": false,
      "indexable": false,
      "nofollow": true,
      "show_counts": true,
      "slider_mode": "double",
      "has_active": true,
      "range": false,
      "values": [
        {
          "id": 26,
          "slug": "l",
          "label": "L",
          "count": 4,
          "active": false,
          "disabled": false,
          "soldout": false,
          "color": "",
          "texture": "",
          "url": "http://127.0.0.1:8306/product-category/vetements/?wsf=taille:m,l"
        },
        {
          "id": 25,
          "slug": "m",
          "label": "M",
          "count": 4,
          "active": true,
          "disabled": false,
          "soldout": false,
          "color": "",
          "texture": "",
          "url": "http://127.0.0.1:8306/product-category/vetements/"
        }
      ]
    }
  ]
}

Les routes d'administration demandent un utilisateur connecté et l'en-tête X-WP-Nonce (ou un mot de passe d'application). Sans droits, la réponse est 401.

POST /wp-json/websource-facetedsearch/v1/cache/flush
→ {"deleted": 12, "products": 16, "indexed": 16, "attribute_lookup": true, "attribute_rows": 30, "cache_version": 8, …}

Variables CSS

Le bloc reprend les variables du thème Websource, avec une valeur de repli pour tout autre thème.

Variable du blocVariable du thèmeRepliRôle
--wsfs-brand--color-brand-600#0f766eCouleur principale (cases cochées, curseur, bouton).
--wsfs-brand-soft--color-brand-50#effaf8Fond des compteurs et des pastilles.
--wsfs-ink--color-ink#14282bTexte.
--wsfs-line--color-line#d9e6e4Bordures et séparateurs.
--wsfs-surface--color-surface#fffFond du panneau.
--wsfs-r--radius-xl1remArrondi des champs et boutons.
--wsfs-w—min(22rem, 88vw)Largeur du tiroir et du volet.
—--radius-2xl1.5remArrondi du panneau.
—--wst-card-shadownoneOmbre du panneau.

Fichiers chargés uniquement sur les listes qui affichent des filtres : assets/front.css, assets/front.js (différé, sans jQuery), et assets/push.css seulement si un mode « volet » est utilisé.

Fonctions publiques

AppelRôle
Frontend::engine(): ?EngineMoteur de la liste de la page en cours (null hors liste filtrable).
Frontend::engineFor(Context $context, array $state): ?EngineMoteur d'un contexte quelconque.
Context::forShop(), Context::forTerm(int $id, string $taxonomy = 'product_cat')Fabriques de contexte.
Engine::total(): intNombre de produits de la sélection.
Engine::facets(): arrayFiltres avec leurs valeurs (id, slug, label, count, active, disabled, soldout, color, texture) ou leur plage (min, max, step, selected_min, selected_max).
Engine::state(): arraySélection en cours, dans l'ordre du modèle.
Engine::mainQueryWhere(string $idExpr): stringConditions SQL de la sélection pour une requête de produits.
Url::build(string $base, array $kept, array $state): stringConstruit une URL filtrée.
Url::serialize(array $state), Url::unserialize(string $encoded)Encode et décode le paramètre d'URL.
Templates::all(), Templates::resolve(string $pageType, array $ancestorIds)Modèles enregistrés, modèle d'une page.
Settings::get(string $name), Settings::pageType(string $type)Lecture des réglages.
Cache::bump(), Cache::flush()Invalide ou vide la mémoire.

Exemple : nombre de produits bleus de la boutique.

use Websource\FacetedSearch\{Context, Frontend};

$engine = Frontend::engineFor(Context::forShop(), ['couleur' => ['bleu']]);
$total = $engine ? $engine->total() : 0;

Données enregistrées

EmplacementContenu
Option wsx_facetedsearch_settingsRéglages.
Option wsx_facetedsearch_templatesModèles de filtres.
Option wsx_facetedsearch_cache_versionVersion de la mémoire.
Option wsx_facetedsearch_tasksDernière préparation.
Transients wsx_fs_*Filtres calculés.
Métadonnées de terme wsx_color, wsx_textureCouleur et texture des valeurs d'attributs.

Aucune table n'est créée. La désinstallation supprime tout ce qui précède.

Écarts par rapport au module PrestaShop

  • Pas de multiboutique (une installation WordPress = une boutique).
  • Pas d'index de prix propre ni de file d'attente : les tables de recherche de WooCommerce jouent ce rôle. Les tâches se réduisent à la préparation de la mémoire (WP-Cron) ; il n'y a ni URL de cron à jeton ni déclenchement « sans cron ».
  • Types de page : boutique, catégories, marques, étiquettes, recherche. Fournisseurs, nouveaux produits, meilleures ventes et promotions n'ont pas de page native dans WooCommerce.
  • Filtres « État » (neuf, occasion) et « Caractéristiques » : pas d'équivalent natif. Les attributs WooCommerce couvrent les caractéristiques ; le curseur sur caractéristique numérique n'est pas repris. Le filtre « Étiquettes » est ajouté.
  • « Soldes » devient « Mis en avant » (produits mis en avant de WooCommerce).
  • Format d'URL : wsf=marques:nordik/couleur:bleu,vert au lieu de q=marques-nordik/couleur-bleu-vert, parce que les identifiants WordPress contiennent des tirets.
  • Titres de filtres par langue : un seul titre, traduit par Polylang ou WPML.
  • Une sélection de plusieurs attributs s'applique au produit, pas à une même variation.