HUSKY - WooCommerce Product Filter Professional

WooCommerce 属性与元字段范围滑块筛选器

尺寸、功率、长度、屏幕对角线、年份、里程:数值型的产品数据更适合用范围滑块,而不是一长串复选框。在 HUSKY 中启用 WooCommerce 属性范围滑块筛选器很容易,但同样容易得到这样的滑块:100000 排在 9000 之前、把 1,9 拆成两个值,或者范围总是从 0 到 100。原因几乎总是相同的:这里有两种不同的滑块,它们处理数字的方式不同。本指南将介绍这两种滑块、各自的设置方法,以及顺序错误、小数和空范围的修复方法。

两种范围滑块:属性值或数值型元字段

HUSKY 可以基于两种数据绘制范围滑块,而这个选择决定了滑块能做什么。

属性(分类法)滑块元字段滑块
数据全局属性或其他产品分类法的术语保存在产品元数据中的数字:_length、_weight、ACF 数字字段、任何自定义字段
范围的含义两个滑块手柄之间的所有术语,按术语列出的顺序真正的数值比较:值介于起点和终点之间
滑块位置每个现有术语对应一个停靠点,等距分布最小值与最大值之间的任意值,按您设定的步长
最小值和最大值第一个和最后一个术语在范围 (Range)选项中手动设置
起止数字输入框无有,显示输入框 (Show inputs)
文字刻度(软、中、硬)支持不支持,仅限数字
可变产品通过产品的属性术语查找只搜索产品自身的元数据,不搜索其变体

关键区别在于:属性术语是文本。WordPress 把 9000 和 100000 作为名称而不是数字来保存,所以属性滑块只能按给定的顺序沿着术语列表移动,它从不进行计算。元字段滑块则在数据库中比较数字,因此可以处理范围内的任何值,包括其他产品都没有的值。

直接在产品的“属性”选项卡上输入、背后没有全局属性的自定义产品属性不是分类法,任何筛选类型都无法使用它们。请先在“产品 → 属性 (Products → Attributes)”下创建全局属性(参见 WooCommerce 文档中的管理产品分类法)。

设置属性范围滑块筛选器

  1. 创建全局属性,例如功率 (Power),并把它的值添加为术语:5、7.5、10、15。像往常一样把它们分配给产品。
  2. 打开 WooCommerce → 设置 → 产品筛选 → 结构 (Structure),将该属性的类型设为滑块 (Slider)。该类型由滑块扩展提供。
  3. 点击属性旁边的附加选项 (additional options)(齿轮)按钮,设置滑块选项:
    • 类型 (Type):double 表示起止范围;single 表示只有一个手柄,选中从第一个值到手柄位置的所有内容(“最高 10 kW”)。
    • 网格步长 (Grid step):滑块下方哪些标签可见。1 显示全部,2 每隔一个显示,-1 隐藏两端之间的标签。当较长的值相互重叠时很有用。
    • 启用动态重新计数 (Enable dynamic recount):去掉当前结果中没有产品的值(见下文)。
    • 滑块皮肤 (Slider skin):此滑块的设计样式。
  4. 将筛选逻辑 (Logic of filtering)保持为 OR。滑块会发送所选区段内的每个术语,例如 pa_power=5,7-5,10,而产品只需匹配其中一个。如果使用 AND,产品就需要匹配全部术语,结果什么也找不到。

由于范围就是“手柄之间的术语”,术语的顺序就是滑块的全部逻辑。如果 6.5 在列表中排在 8.2 之后,那么 6 到 7 的范围就会跳过它。下一节将解决顺序问题。

属性滑块的值顺序错误

典型症状:100000 排在 9000 之前,10 和 11 排在 2 之前,负值按 -1、-2、-3、0、1 排列,或者拖动时手柄来回跳动。这些都是文本排序造成的。解决办法是为术语指定数值顺序。

最佳方案:让 WooCommerce 按数值对属性排序

进入“产品 → 属性 (Products → Attributes)”,编辑该属性,并将默认排序 (Default sort order)设为名称(数值) (Name (numeric))。这样 WooCommerce 会按术语名称的数值来排序,可以正确处理以点号书写的小数、负数,以及以数字开头的名称,例如 10 cm。在滑块的附加选项中,请将术语排序 (Sort terms)保持为默认 (Default),这样 HUSKY 会沿用该顺序。如果启用了缓存术语 (Cache terms)(高级 → 选项),之后请点击清除术语缓存 (clear terms cache)。

对于文字刻度,请改为选择自定义排序 (Custom ordering),并在属性的配置术语 (Configure terms)界面中把术语拖到合适的位置:软、中、中硬、硬。对于任何需要手动控制顺序的数值列表,同样可以使用这种拖放方式。

HUSKY 自带的术语排序选项

滑块附加选项中的术语排序 (Sort terms)选项会覆盖默认顺序:

  • 标题 (Title)使用名称的自然排序:对于正整数(2 在 10 之前)和 10 cm 这样的名称是正确的,但不适用于小数或负数。
  • 数值 (Numeric.)比较术语别名 (slug)的整数值。它只适用于正整数:6.5 的别名是 6-5,被当作 6;而 WordPress 在生成别名时会去掉开头的负号,所以 -3 会被当作 3 来排序。

代码:为任何分类法滑块设置数值顺序

对于自定义分类法,WooCommerce 的名称(数值) (Name (numeric))不可用,此时可通过代码对滑块的值排序。woof_sort_terms_before_out 过滤器会接收每个筛选器的术语和筛选类型:

/**
 * HUSKY: order the values of every taxonomy range slider by their number
 * (decimals with a dot and negative numbers included).
 * Child theme functions.php or a code snippets plugin.
 */
add_filter( 'woof_sort_terms_before_out', function ( $terms, $type ) {
    if ( 'slider' === $type && is_array( $terms ) ) {
        uasort( $terms, function ( $a, $b ) {
            return (float) $a['name'] <=> (float) $b['name'];
        } );
    }
    return $terms;
}, 20, 2 );

不以数字开头的术语(文字刻度)在这里都按 0 计算并保持原有顺序,因此该代码片段不会影响此类滑块。

属性滑块中的小数、逗号和不均匀的步长

  • 小数请用点号书写。滑块以逗号分隔的列表接收其标签,所以名为 1,9 的术语会变成两个标签 1 和 9,其后的每个位置都会指向错误的术语。请把这类术语重命名为 1.9。这与商店的小数分隔符设置无关:术语名称是纯文本。
  • 位置按术语均匀分布,而不是按数值。术语 1、2、5 和 50 会得到四个等距的步长。如果希望滑块看起来成比例,请把缺少的中间值添加为术语。
  • 滑块至少需要两个值。只有两个术语时,手柄只能停在两端。动态重新计数之后剩余的值少于两个时,滑块将完全不显示。
  • 只能选择已存在的术语。值为 6.5 的产品,只有在术语 6.5 存在并且位于两个手柄之间时才能被找到。

元字段范围滑块:尺寸、年份和其他数字

当数值是真实的测量值时,元字段滑块通常是更好的工具:它比较的是数字,支持起止输入框,并且在有成千上万个不同值时仍能保持快速。使用元字段扩展的设置方法如下:

  1. 打开筛选器设置的元数据 (Meta Data)选项卡。在手动添加自定义键 (Add Custom key by hands)下输入键名,或使用通过产品 ID 获取任意产品的键 (Get keys from any product by its ID)查看某个产品有哪些键。
  2. 将字段的类型设为number,视图设为滑块 (Slider)。文本或日期字段不提供滑块。保存。
  3. 打开该字段的附加选项,将范围 (Range)填写为 min^max,例如 10^250。设置步长 (Step)(0.5 可行),并在需要时设置前缀 (Prefix)、后缀 (Postfix)(cm)、用于起止数字输入框的显示输入框 (Show inputs),以及用于千位分隔符的使用美化显示 (Use prettify)。
  4. 像其他筛选项一样,在结构 (Structure) 选项卡中放置这个新的筛选项。

常用的键:WooCommerce 把产品的运输尺寸和重量保存为 _length、_width、_height 和 _weight。ACF 数字字段则以其字段名称保存。有关元数据键的详情,请参阅元数据文档。

关于元字段滑块需要了解的事项:

  • 范围从不自动计算。滑块显示的正是您输入的范围 (Range);字段为空时回退为 0–100。要找出真实的最小值和最大值,就得在每次页面访问时读取所有产品。动态重新计数决定显示哪些筛选器和值,而不是滑块的起点和终点。当新产品超出范围时,请更新范围。
  • 请存储纯数字,以点号作为小数分隔符,且不使用千位分隔符:1250.5。数据库只读取值开头的数字,所以 1,250.5 会被当作 1 比较,1250,5 会被当作 1250。
  • 年份:范围例如 1990^2026,步长 1,并将使用美化显示 (Use prettify)设为否 (No),否则 2026 会显示为 2 026。
  • 变体:搜索的是产品自身的元数据。如果该值只存在于变体上,请同时把它保存到父产品上,或者改用属性。

小数值:woof_slider_meta_query_type

默认情况下,元字段滑块以 NUMERIC 比较数值,MySQL 会将其视为整数。因此值为 10.11 的产品会在 1–10 的范围内被找到,而 4.2、4.4 和 4.6 都被算作 4。若要比较小数,请使用 woof_slider_meta_query_type 过滤器更改类型:

/**
 * HUSKY: compare these meta sliders as decimal numbers.
 * Child theme functions.php or a code snippets plugin.
 */
add_filter( 'woof_slider_meta_query_type', function ( $type, $meta_key ) {
    if ( in_array( $meta_key, array( '_length', '_width', '_height', 'screen_size' ), true ) ) {
        return 'DECIMAL(10,2)'; // up to 99999999.99
    }
    return $type;
}, 10, 2 );

在 DECIMAL(M,D) 中,M 是数字总位数,D 是小数点后的位数。请根据最大值来选择:使用 DECIMAL(5,3) 时,最大值为 99.999,所有更大的值都按 99.999 处理。

隐藏不适用于当前分类的滑块

  • 属性滑块:在其附加选项中将启用动态重新计数 (Enable dynamic recount)设为是 (Yes)。当前分类和筛选选择中没有产品的值会消失,剩余值少于两个时滑块会被移除。每个值都会多一次计数查询,因此对于有数百个术语的属性,请留意页面速度,或者改用元字段滑块。
  • 元字段滑块:在选项选项卡上将隐藏空术语 (Hide empty terms)设为是 (Yes)后,如果当前结果中没有产品落在其范围内,该元字段滑块就不会显示。

没有值的属性滑块会在页面加载后被插件脚本移除,因此它的标题可能会闪现片刻。下面的 CSS 可以从一开始就隐藏它(外观 → 自定义 → 额外 CSS,或您的子主题样式表):

/* HUSKY: hide empty taxonomy sliders before the script removes them */
.woof_container_slider:has(.woof_hide_slider) {
    display: none;
}

当产品本身是一个范围时

滑块按每个产品一个值来查找产品。如果产品覆盖一个范围(适合身高 150–190 cm,3–10 名玩家),则没有内置的“范围重叠”搜索。有两种可行的模型:

  • 两个元字段,例如 players_min 和 players_max,各有一个滑块。想找适合 4 名玩家的游戏的访客,把第一个滑块设为 1–4,第二个滑块设为 4–10。
  • 一个属性,每个值对应一个术语(150、151 ... 190),把所有适合的术语都分配给产品,并将该属性显示为滑块。请批量分配术语,而不是手动逐个分配。

检查清单

  • 属性滑块:全局属性,小数以点号书写,默认排序 (Default sort order)设为名称(数值) (Name (numeric))或将术语拖放到位,筛选逻辑 (Logic of filtering)保持为 OR。
  • 元字段滑块:字段类型为number,使用纯数字值,范围 (Range)填写为 min^max,小数值使用小数类型。
  • 有大量不同的值或真实的测量值:使用元字段滑块,而不是包含数百个术语的属性。
  • 滑块出现在错误的分类中:属性滑块使用启用动态重新计数 (Enable dynamic recount),元字段滑块使用隐藏空术语 (Hide empty terms)。

如果按这些步骤操作后滑块仍显示错误的值,请到 HUSKY 支持论坛提问,并附上属性或元数据键、几个示例值以及页面链接。