如何按属性术语菜单顺序对WooCommerce产品进行排序
注:你描述中提到的「产品 > 属性 > size」路径应为笔误,以下方案默认你调整的是brand产品属性的术语菜单顺序。
实现方案
你判断的方向没错,通过pre_get_posts钩子配合SQL查询自定义就能实现需求,核心是调用WooCommerce存在术语元表中的自定义排序值排序。
将以下代码添加到当前主题的functions.php文件,或者自定义功能插件的主文件中即可:
// 修改商品主查询,按品牌自定义菜单顺序排序 add_action('pre_get_posts', 'custom_sort_products_by_brand_menu_order'); function custom_sort_products_by_brand_menu_order($query) { // 仅作用于前台、主查询、店铺页面(如果需要同时作用于商品分类/标签页,可新增is_product_taxonomy()条件) if (!is_admin() && $query->is_main_query() && is_shop()) { add_filter('posts_join', 'custom_brand_order_join_clause'); add_filter('posts_orderby', 'custom_brand_order_orderby_clause'); } return $query; } // 关联查询品牌术语的排序元数据 function custom_brand_order_join_clause($join) { global $wpdb; // 关联产品和术语的关联表 $join .= " LEFT JOIN {$wpdb->term_relationships} tr ON {$wpdb->posts}.ID = tr.object_id "; // 筛选brand属性对应的术语(WooCommerce属性分类法前缀为pa_,如果你的brand属性slug不是brand,需要对应修改pa_brand) $join .= " LEFT JOIN {$wpdb->term_taxonomy} tt ON tr.term_taxonomy_id = tt.term_taxonomy_id AND tt.taxonomy = 'pa_brand' "; // 取术语的自定义排序值 $join .= " LEFT JOIN {$wpdb->termmeta} tm ON tt.term_id = tm.term_id AND tm.meta_key = 'order' "; return $join; } // 自定义排序规则 function custom_brand_order_orderby_clause($orderby) { global $wpdb; // 优先按品牌菜单顺序升序,同品牌下按产品发布时间降序排序,二级排序规则可自行修改 $orderby = " COALESCE(tm.meta_value, 999) ASC, {$wpdb->posts}.post_date DESC "; // 执行完成后移除过滤器,避免影响其他查询 remove_filter('posts_join', 'custom_brand_order_join_clause'); remove_filter('posts_orderby', 'custom_brand_order_orderby_clause'); return $orderby; }
注意事项
- WooCommerce的产品属性对应的分类法默认前缀为
pa_,如果你的brand属性的slug不是brand,需要把代码中的pa_brand修改为你实际的属性分类法名称 - 代码中
COALESCE(tm.meta_value, 999)的作用是将未关联任何brand属性的产品排到列表最后,你可以修改999这个值调整这类产品的排序位置,或者删除这个逻辑 - 如果需要自定义同品牌下的产品排序规则,只需要修改
$orderby中的二级排序字段即可,比如按价格升序、销量降序都可以 - 添加代码后清空网站缓存(页面缓存、对象缓存)即可生效
内容的提问来源于stack exchange,提问作者Jordan Carter
相关产品推荐
相关产品推荐

