如何用自定义代码让指定WooCommerce产品在销量排序时置顶
实现WooCommerce指定产品置顶+销量降序排序
完全可以通过自定义代码实现这个需求,不需要依赖额外插件。核心思路是通过WooCommerce和WordPress的查询钩子,在销量降序排序的基础上,强制指定ID的产品排在列表最顶部。
具体代码实现
将以下代码添加到当前主题的functions.php文件,或者使用自定义代码管理插件(比如Code Snippets)来添加:
// 定义需要置顶的产品ID集合 function custom_sticky_product_ids() { return array(123, 456, 789); // 替换成你需要置顶的产品ID } // 拦截WooCommerce排序参数,适配置顶逻辑 add_filter('woocommerce_get_catalog_ordering_args', 'custom_sticky_products_order_args'); function custom_sticky_products_order_args($args) { // 仅当用户选择"销量"排序时触发逻辑 if ($args['orderby'] === 'sales') { $sticky_ids = custom_sticky_product_ids(); $args['orderby'] = 'post__in'; $args['order'] = 'ASC'; $args['post__in'] = $sticky_ids; // 排除已置顶的产品,避免重复 $all_product_ids = get_posts(array( 'post_type' => 'product', 'numberposts' => -1, 'fields' => 'ids' )); $args['post__not_in'] = array_diff($all_product_ids, $sticky_ids); } return $args; } // 调整最终SQL排序语句,确保置顶产品在前,其余按销量降序 add_filter('posts_orderby', 'custom_sticky_products_orderby', 10, 2); function custom_sticky_products_orderby($orderby, $query) { global $wpdb; // 仅在产品归档/分类/标签页生效 if ((is_shop() || is_product_category() || is_product_tag()) && $query->get('orderby') === 'post__in') { $sticky_ids = implode(',', custom_sticky_product_ids()); if (!empty($sticky_ids)) { // 先按指定ID排序(置顶),再按销量降序排列剩余产品 $orderby = "FIELD({$wpdb->posts}.ID, {$sticky_ids}) DESC, {$wpdb->postmeta}.meta_value+0 DESC"; } } return $orderby; }
代码说明
custom_sticky_product_ids():专门用来维护需要置顶的产品ID,把你要固定的产品ID替换进去即可,多个ID用逗号分隔。woocommerce_get_catalog_ordering_args:拦截WooCommerce的排序参数,当用户选择“销量”排序时,调整查询规则优先加载置顶产品。posts_orderby:修改最终的数据库查询排序逻辑,确保置顶产品排在最前面,剩下的产品继续按销量从高到低排序。
注意事项
- 代码添加后,记得清空WooCommerce和WordPress的缓存,确保新的排序规则生效。
- 如果你使用了缓存插件(比如WP Rocket、W3 Total Cache),也需要清空插件缓存。
- 建议在测试环境先验证代码,避免影响线上业务;或者备份网站后再操作。
内容的提问来源于stack exchange,提问作者Fredrik
相关产品推荐
相关产品推荐

