HUSKY - WooCommerce Product Filter Professional

WooCommerce 筛选器:仅显示当前分类的属性

当多个产品分类共用同一个属性时,WooCommerce 筛选器常常会提供在当前页面上毫无意义的值:冰箱分类下出现烧烤架 (Grill),耳机分类下出现 512 GB,还有这个分类根本不销售的品牌。点击它们只会得到空结果。为了让 WooCommerce 筛选器只显示当前分类的属性,HUSKY 会统计页面上每个术语背后的产品数量,并隐藏数量为零的术语。下文说明其工作原理、确切的设置、如何让数字不可见,以及根本无法确定分类的情况。

筛选器如何知道哪些内容属于当前分类

在产品分类页面以及其他任何产品分类法归档页(标签、属性归档、品牌)上,HUSKY 会记住该页面所展示的术语。开启动态重新计数 (Dynamic recount) 后,每个筛选术语旁边的数字按如下方式计算:属于本分类、符合访客已选的所有条件、并且同样具有该术语的产品数量。分类中没有任何产品具有的值,计数为 0。

随后,隐藏空术语 (Hide empty terms) 会把表单中所有计数为 0 的术语移除。当某个区块的所有术语都被移除时,整个区块(包括标题)也会消失,因此分类中未使用的属性会从侧边栏中消失。分类区块本身则会被裁剪为当前所查看分类的子分类;这部分及其例外情况在为什么筛选器只显示子分类中有说明。

无需为每个分类单独配置。同一个表单放在侧边栏或分类模板中,会自行适应每一个分类页面。

隐藏空术语的三个设置

打开插件设置的选项 (Options) 标签页,并设置:

  1. 显示计数 (Show count):是
  2. 动态重新计数 (Dynamic recount):是
  3. 隐藏空术语 (Hide empty terms):是

保存后,请清除所有可能保存旧计数的缓存:如果您使用了它们,则包括高级 (Advanced) → 选项 (Options) 中的缓存筛选器中每个项目的动态重新计数结果 (Cache dynamic recount number for each item in filter) 和缓存术语 (Cache terms),以及网站的页面缓存。

这三个选项相互依赖,设置页面也会强制执行这一点:空术语只能通过计数才能找到。开启隐藏空术语 (Hide empty terms) 时,另外两项也会随之开启;关闭显示计数 (Show count) 时,另外两项也会随之关闭。如果您为了去掉数字而把显示计数 (Show count) 设为“否”,空术语就会在每个页面上重新出现。可能的组合如下:

显示计数 / 动态重新计数 / 隐藏空术语访客看到的内容
否 / 否 / 否所有术语,没有数字
是 / 否 / 否全店范围的数字;没有任何产品的术语显示为灰色
是 / 是 / 否当前分类和所选条件下的数字;计数为零的术语保持可见但显示为灰色,无法选择
是 / 是 / 是计数为零的术语被隐藏;空区块消失

如果您希望把不可用的值显示为未激活状态而不是直接移除,第三行就是您的选择。还有几处可以覆盖全局选项:

  • 在免费版中,隐藏空术语 (Hide empty terms) 和隐藏术语计数文本 (Hide terms count text)(见下文)显示为灰色;它们属于高级版功能。
  • HUSKY 筛选器小工具有自己的动态重新计数 (Dynamic recount) 字段(默认 (Default)、否 (No)、是 (Yes))。如果设为否 (No),该小工具会忽略全局设置。[woof] 短代码有相同的开关,即 dynamic_recount=1 或 dynamic_recount=0。
  • 启用涡轮模式后,选项 (Options) 标签页会显示这三个设置在涡轮模式下的独立副本。启用后请重新设置一遍。
  • 以范围滑块形式显示的分类法不会受全局选项的重新计数影响。请打开它的附加选项(结构 (Structure) 标签页中该分类法旁边的齿轮图标),并把启用动态重新计数 (Enable dynamic recount) 设为“是”;没有产品的值随后会被排除在滑块刻度之外。

选项标签页文档介绍了同一屏幕上的其他设置。

隐藏空术语但不显示计数

最常见的需求是隐藏空术语,同时不打印 (12) 这样的数字。请保持三个选项都开启,然后进入高级 (Advanced) → 选项 (Options):把隐藏术语计数文本 (Hide terms count text) 设为“是”。插件仍会计算计数(它需要计数才能知道哪些术语为空),但不会把它们打印出来。如果只想对某一个表单这样做,请在它的短代码中加入 hide_terms_count=1,例如 [woof hide_terms_count=1]。

用 CSS 隐藏计数器对复选框和单选按钮同样有效(.woof_checkbox_count、.woof_radio_count),但对下拉菜单无效:在下拉菜单里,数字是选项文本的一部分,没有独立的元素。而该设置适用于所有筛选类型。

如果只想在某些区块中更改计数器,请使用 woof_term_count_format 钩子。它接收格式(默认为 (%d))和分类法别名:

/*
 * HUSKY: counter format per filter section.
 * Child theme functions.php or a code snippets plugin.
 */
add_filter('woof_term_count_format', function ($format, $tax_slug) {
    // no numbers at all in the Tags and Brand sections
    if (in_array($tax_slug, array('product_tag', 'pa_brand'), true)) {
        return '';
    }
    // "12" instead of "(12)" everywhere else
    return '%d';
}, 10, 2);

这些区块中的空术语仍然会被隐藏,因为隐藏取决于计算出的计数,而不是打印出的文本。如果只想在分类树的最底层显示数字,请用 CSS 隐藏有子级的术语的计数器(放在主题的自定义 CSS 字段中):

.woof_childs_list_li > .woof_checkbox_label > .woof_checkbox_count {
    display: none;
}

已选中的术语从不显示数字。这是设计使然:重新计数会跳过已经属于搜索条件的术语。

为什么第一次选择之后其他值会消失

动态重新计数会随着每次选择缩小表单的范围:选择了品牌:博世 (Brand: Bosch) 之后,只会保留本分类中博世产品所具有的颜色。这正是该功能的意义所在。它无法只针对某一个区块关闭。

另一种情况是,选择了一种颜色就把所有其他颜色都隐藏了。这来自该区块的逻辑。请打开该分类法的附加选项(结构 (Structure) 标签页中的齿轮图标),查看筛选逻辑 (Logic of filtering):

  • OR(默认):至少具有一个所选值的产品。其他每种颜色都单独计数(在其他区块的选择范围内),因此该分类中存在的颜色会保留下来。
  • AND:同时具有所有所选值的产品。其他每种颜色的计数变成“同时是红色和蓝色的产品”,通常为 0,因此在开启隐藏空术语 (Hide empty terms) 时它们会消失。
  • NOT IN:排除具有所选值的产品。

对于颜色、尺寸以及大多数访客想要“这个或那个”的属性,OR 才是正确的逻辑。AND 则留给必须同时具备的特性,例如“Wi-Fi 和蓝牙”。

对于在加载任何产品之前就要逐步缩小范围的选项(由相互依赖的下拉菜单组成的查找器),请使用 [woof ajax_redraw=1 autosubmit=1]:每次更改只会用重新计数后的选项重绘表单,筛选按钮才会加载产品。ajax_redraw 不适用于 AJAX 模式,因此请对该表单保持尝试对商店启用 AJAX (Try to ajaxify the shop) 关闭。

商店页、自定义页面和页面构建器

自动缩小范围需要分类法归档页。在其他地方,不存在当前分类:

  • 主商店页展示整个商品目录,因此在访客选择任何内容之前,只有整个商店中没有任何产品的值会被隐藏。这是正确的行为。
  • WordPress 页面(首页、着陆页,或用 Elementor 或 Divi 构建的、列出某一个分类的页面)不是分类归档页,即使它只显示该分类的产品也是如此。筛选器无从得知这一点,因此会列出所有内容。

在这样的页面上,请告诉两个短代码该页面讲的是哪个分类。请使用产品 → 分类 (Products → Categories) 中的术语 ID:

[woof taxonomies=product_cat:15]
[woof_products taxonomies=product_cat:15 per_page=12]

[woof] 的 taxonomies 属性让计数和隐藏跟随该分类,而 [woof_products] 中的同一属性则限定所显示的产品。同一分类法的多个 ID 用逗号分隔(product_cat:15,16,属于其中任一分类的产品),多个分类法用加号连接(product_cat:15+pa_color:22)。只有在上述三个选项都开启时它才有效。此类页面的完整设置见自定义页面或首页上的产品筛选器。

如果您需要的是每个分类使用不同的区块集合,而不是不同的值,请参阅如何为每个分类显示不同的筛选器。

如果真正的分类归档页上的筛选器仍然表现得像在商店页上一样,可能是主题的归档模板对插件隐藏了当前分类;这主要发生在基于区块的模板上。请在高级 (Advanced) → 选项 (Options) 中把分类页面的附加检查 (Additional check of the category page) 设为“是”。

不使用动态重新计数的轻量方案

如果您只需要隐藏整个商店中没有任何产品的术语(旧的尺寸、已停止销售的品牌),就不需要动态重新计数。下面这段代码会让 WordPress 在 HUSKY 加载术语时跳过这类术语:

/*
 * HUSKY: do not list terms that have no published products at all.
 * Child theme functions.php or a code snippets plugin.
 */
add_filter('woof_get_terms_args', function ($args) {
    $args['hide_empty'] = true;
    return $args;
});

它在页面加载时不消耗任何资源,但它不了解当前分类或访客的选择:只存在于鞋类中的尺寸,仍然会显示在衬衫分类里。如果缓存术语 (Cache terms) 已开启,添加代码后请清除术语缓存。常见问题如何隐藏空术语展示了同样的代码。

动态重新计数在大型商品目录上的代价

表单中的每个术语在每次页面浏览时都需要自己的计数查询(包括被隐藏的术语),因此一个有 300 个术语的表单大约会执行 300 次计数查询。在几千个产品上这几乎察觉不到;在几万个产品上,它可能拖慢每个分类页面。在关闭该功能之前:

  • 在高级 (Advanced) → 选项 (Options) 中启用缓存筛选器中每个项目的动态重新计数结果 (Cache dynamic recount number for each item in filter);
  • 在不需要缩小范围的表单上使用 dynamic_recount=0,例如页眉中的搜索表单;
  • 考虑使用涡轮模式,它从预先准备好的数据文件而不是数据库查询来进行筛选和计数。

详情见如何加速大型商品目录中的产品筛选。

仍然显示无关选项时的检查清单

  • 显示计数 (Show count)、动态重新计数 (Dynamic recount) 和隐藏空术语 (Hide empty terms) 全部为“是”(如果启用了涡轮模式,则是它们的涡轮模式副本)。
  • 数字是通过隐藏术语计数文本 (Hide terms count text) 隐藏的,而不是把显示计数 (Show count) 设为“否”。
  • 小工具的动态重新计数 (Dynamic recount) 字段为默认 (Default) 或是 (Yes);短代码中没有 dynamic_recount=0。
  • 您是在真正的分类归档页上测试,或者自定义页面上的短代码带有 taxonomies=。
  • 修改之后,重新计数缓存、术语缓存和页面缓存都已清除。
  • 如果选择之后需要保留其他值,该属性的筛选逻辑 (Logic of filtering) 为 OR。

如果以上都已就位,而某个分类仍然列出没有产品的值,请在 HUSKY 支持论坛上发起一个主题,附上该分类页面的链接以及应该被隐藏的值。