WOOT - WooCommerce Active Products Tables

Filtre de catégories d’un tableau de produits WooCommerce : logique et ordre

Le filtre de catégories d’un tableau de produits WooCommerce transforme chaque catégorie sélectionnée par un visiteur en condition d’une requête de taxonomie WordPress, et relie les catégories choisies avec la logique que vous avez définie pour cet élément de filtre. La plupart des surprises viennent de cette logique, par exemple une sous-catégorie qui affiche encore tous les produits de sa catégorie parente. Voici comment le filtre construit sa requête, comment le configurer pour les catégories parentes et enfants, comment changer l’ordre des termes dans les listes déroulantes, ainsi que deux cas voisins : le filtre En promotion (On Sale) et les filtres pendant les imports de produits.

Comment le filtre de catégories d’un tableau de produits construit sa requête

Les filtres de taxonomie s’ajoutent dans l’onglet Filtre (Filter) d’un tableau. Toute taxonomie de produit peut devenir un élément de filtre : Catégories de produits (Product categories), Étiquettes de produits (Product tags), chaque attribut global (pa_color, pa_size, etc.) et les taxonomies de produits personnalisées. Cliquez sur le bouton en forme d’engrenage d’un élément pour ouvrir ses options (la fenêtre s’intitule Table #12; filter field: product_cat). Quatre options comptent ici :

OptionCe qu’elle fait
Sélection multiple (MultiSelect)Désactivée : une liste déroulante classique, un terme à la fois. Activée : une liste à sélection multiple, le visiteur peut choisir plusieurs termes.
Logique (Logic)IN, AND ou NOT IN : la manière dont les termes sélectionnés de cet élément sont combinés.
Exclure (Exclude)ID de termes séparés par des virgules, retirés de la liste déroulante.
Inclure (Include)ID de termes séparés par des virgules : seuls ces termes sont listés.

Lorsque le visiteur sélectionne des termes, le plugin ajoute à la requête de produits une clause pour cet élément : les ID des termes sélectionnés avec l’opérateur défini dans Logique (Logic).

  • IN (par défaut, la logique « OU ») : les produits présents dans au moins l’un des termes sélectionnés.
  • AND : les produits présents dans tous les termes sélectionnés à la fois.
  • NOT IN : les produits présents dans aucun des termes sélectionnés. Utile pour un filtre de type « exclusion ».

Des éléments de filtre différents sont toujours combinés avec AND : une catégorie, une couleur et une tranche de prix doivent toutes correspondre. Le filtre n’agit en outre que sur les produits que le tableau affiche déjà ; les règles de l’onglet Prédéfinition (Predefinition) s’appliquent donc en premier. L’option Logique (Logic) appartient à un tableau créé dans WOOT → Tableaux (Tables) ; un tableau généré à partir d’attributs de shortcode, sans ID de tableau, utilise toujours IN.

Catégories parentes et enfants dans le filtre de catégories

Les catégories de produits sont hiérarchiques, et dans une requête de taxonomie WordPress traite par défaut une catégorie comme « cette catégorie et toutes ses sous-catégories », ce que fait aussi le filtre. Cela explique la plainte la plus fréquente : un visiteur sélectionne Visage puis Acné dans une liste à sélection multiple, et le tableau affiche toujours tout ce qui se trouve dans Visage. Avec IN, le parent seul correspond déjà à tous les produits de toutes ses sous-catégories ; ajouter une sous-catégorie ne peut donc rien restreindre.

Passer Logique (Logic) sur AND est rarement la solution pour les catégories. WordPress étend chaque catégorie sélectionnée à toutes ses sous-catégories, puis exige qu’un produit appartienne à chacune d’elles. Sélectionner un parent avec AND revient donc à demander les produits affectés au parent et à chacune de ses sous-catégories, c’est-à-dire le plus souvent aucun. Deux sous-catégories avec AND n’affichent que les produits affectés aux deux. Il n’y a qu’une seule logique par élément de filtre ; vous ne pouvez pas utiliser IN pour certains termes d’une taxonomie et AND pour d’autres.

Ce qui fonctionne en pratique :

  • Une liste déroulante simple. Laissez Sélection multiple (MultiSelect) désactivée. Le visiteur choisit exactement une catégorie, et choisir Acné remplace Visage : le tableau n’affiche donc que Acné (et les catégories situées en dessous).
  • Une sélection multiple avec IN, pour des catégories du même niveau. Sélectionner Acné et Peau sèche affiche les produits de l’une ou de l’autre. Le résultat ne dérape que si un parent est sélectionné en plus.
  • Une liste plus courte avec Exclure ou Inclure. La liste déroulante est construite comme une arborescence, du niveau supérieur vers le bas, et une sous-catégorie n’est listée que si son parent l’est. Exclure un parent retire toute sa branche, et Inclure (Include) doit contenir aussi les ID des parents, faute de quoi leurs sous-catégories n’apparaissent jamais. Vous trouvez l’ID d’un terme dans Produits → Catégories (ou Produits → Attributs → Configurer les termes (Configure terms)) : survolez le terme et lisez tag_ID= dans le lien de modification.
  • Un tableau distinct pour chaque rubrique de la boutique. Si une page porte sur une seule catégorie parente, limitez son tableau à cette catégorie dans Prédéfinition et ne filtrez que ses sous-catégories. Voir des tableaux différents pour des catégories différentes.

Les attributs et les étiquettes n’ont pas de hiérarchie, AND y fonctionne donc comme prévu : Couleur (Color) avec AND et les termes Rouge et Bleu affiche les produits qui possèdent les deux. Un produit variable « a » tous les termes d’attribut listés dans ses attributs, quelle que soit la variation en stock.

Ordre des termes dans les listes déroulantes du filtre

Les listes déroulantes affichent les termes de chaque niveau par ordre alphabétique de nom, avec les sous-catégories sous leur parent, signalées par un tiret par niveau. Les termes sans produit publié ne sont pas listés. L’ordre que vous définissez dans WooCommerce, en faisant glisser les catégories dans Produits → Catégories ou avec Ordre de tri par défaut (Default sort order) → Ordre personnalisé (Custom ordering) d’un attribut, n’est pas utilisé, et Inclure (Include) ne modifie pas non plus l’ordre : cette option décide seulement quels termes apparaissent.

Pour lister les catégories et les attributs dans l’ordre de WooCommerce, ajoutez ce code. Il ne modifie que les requêtes qui construisent le filtre du tableau, pas les autres listes de termes du site.

/*
 * WOOT table filter: list product categories and attribute terms in the
 * order set in WooCommerce instead of alphabetically.
 * Child theme functions.php or a code snippets plugin.
 */
add_filter('woot_profile_extend', function ($profile) {
    foreach ($profile as $key => $field) {
        if (!is_array($field) || empty($field['get_filter_draw_data']) || !taxonomy_exists($key)) {
            continue;
        }
        if ('product_cat' !== $key && !taxonomy_is_product_attribute($key)) {
            continue;
        }

        $draw = $field['get_filter_draw_data'];

        $profile[$key]['get_filter_draw_data'] = function ($table_id) use ($draw) {
            $shop_order = function ($query) {
                $taxonomy = current((array) $query->query_vars['taxonomy']);
                $query->query_vars['orderby'] = taxonomy_is_product_attribute($taxonomy) ? wc_attribute_orderby($taxonomy) : 'menu_order';
            };

            add_action('pre_get_terms', $shop_order, 5);
            $data = $draw($table_id);
            remove_action('pre_get_terms', $shop_order, 5);

            return $data;
        };
    }

    return $profile;
});

Pour les attributs, le code suit l’Ordre de tri par défaut (Default sort order) propre à chaque attribut (Ordre personnalisé (Custom ordering), Nom (Name), Nom (numérique) (Name (numeric)) ou ID du terme (Term ID)) ; les catégories suivent leur ordre de glisser-déposer. Il utilise woot_profile_extend, le hook qui expose les champs du tableau. La liste des termes est écrite dans la page au moment où celle-ci est générée ; videz donc le cache de page après avoir ajouté le code.

Le filtre En promotion et les produits variables

L’élément de filtre En promotion (On Sale) est un interrupteur. Lorsqu’il est activé, le tableau n’affiche que les produits issus de la liste de produits en promotion de WooCommerce. Cette liste contient tous les produits ayant un prix promotionnel actif ainsi que le parent de chaque variation ayant un prix promotionnel actif ; un produit variable apparaît donc dès qu’au moins une de ses variations est en promotion.

WooCommerce conserve cette liste dans un cache (le transient wc_products_onsale) et l’actualise lorsqu’un produit est enregistré et lorsqu’une promotion programmée commence ou se termine. Si des prix promotionnels ont été écrits directement dans la base de données, par exemple par un import qui contourne WooCommerce, le filtre peut passer à côté de ces produits. Videz le cache dans WooCommerce → État (Status) → Outils (Tools) → Transients WooCommerce (WooCommerce transients) → Vider les transients (Clear transients).

Les filtres pendant les imports de produits

Tout ce que contient le filtre est lu dans la base de données : les termes des listes déroulantes (uniquement ceux qui ont des produits) et les bornes des curseurs de plage. Pendant qu’un import (WP All Import ou tout autre) est en cours, les produits, les termes et leurs compteurs changent ; les listes déroulantes peuvent alors manquer de termes et les bornes des curseurs être erronées. Ce n’est pas une erreur du filtre, et cela cesse avec la fin de l’import. Deux points pratiques :

  • Lancez les imports volumineux lorsque le trafic est faible, ou sur une copie de préproduction.
  • La liste des termes du filtre fait partie du HTML de la page. Si vous utilisez un cache de page, purgez-le après l’import, sinon les visiteurs conservent la liste telle qu’elle était au moment de la mise en cache de la page.

Si le filtre affiche encore de mauvais produits

  • Ouvrez les options (engrenage) de l’élément et vérifiez Logique (Logic) : IN pour « l’un quelconque », AND pour « tous », NOT IN pour « aucun ».
  • Pour les catégories, testez avec une seule sous-catégorie sélectionnée et sans parent : si le résultat est correct, c’est le parent présent dans la sélection qui était en cause.
  • Vérifiez le produit lui-même : un produit affecté directement à la catégorie parente correspond au parent, pas à une sous-catégorie.
  • Rappelez-vous les règles de Prédéfinition : le filtre n’affiche jamais les produits que le tableau exclut.
  • Après avoir modifié des termes ou le code d’ordre, videz le cache de page et rechargez la page en étant déconnecté.

Si le résultat ne correspond toujours pas aux catégories de vos produits, ouvrez un sujet sur le forum d’assistance WOOT en indiquant le shortcode du tableau, les réglages du filtre et un exemple de produit, et nous vérifierons.