如何实现WooCommerce产品循环中特色产品始终优先显示(无视排序选项)
让WooCommerce特色产品在所有排序结果中优先显示
你的原代码问题在于强制覆盖了用户选择的排序规则,固定成了「特色标记+日期」排序,导致其他排序选项(比如价格、销量)无法生效。要实现“每种排序结果里特色产品优先”,需要保留用户选择的排序逻辑,仅将特色产品的优先级前置。
以下是修正后的代码:
function custom_featured_products_first( $query ) { // 仅针对WooCommerce产品的主查询(商店页、产品分类/标签归档页) if ( $query->is_main_query() && ( is_shop() || is_product_category() || is_product_tag() ) && $query->get('post_type') === 'product' ) { // 获取当前用户选择的排序规则与排序方向 $current_orderby = $query->get('orderby'); $current_order = $query->get('order') ?: 'DESC'; // 基础排序:特色产品优先(_featured存储为1/0,用meta_value_num做数字排序) $new_orderby = array( 'meta_value_num' => 'DESC', ); // 保留用户选择的排序规则,追加到特色排序之后 if ( $current_orderby ) { switch ( $current_orderby ) { case 'price': $new_orderby['meta_value_num'] = 'ASC'; $query->set('meta_key', '_price'); break; case 'price-desc': $new_orderby['meta_value_num'] = 'DESC'; $query->set('meta_key', '_price'); break; case 'sales': $new_orderby['meta_value_num'] = 'DESC'; $query->set('meta_key', 'total_sales'); break; case 'date': $new_orderby['date'] = $current_order; break; case 'title': $new_orderby['title'] = $current_order; break; case 'menu_order': $new_orderby['menu_order'] = 'ASC'; break; // 若有自定义排序选项,在此追加case处理 } } // 重置meta_key为特色标记,确保特色排序生效 $query->set('meta_key', '_featured'); // 应用合并后的排序规则 $query->set('orderby', $new_orderby); } } add_action( 'pre_get_posts', 'custom_featured_products_first' );
关键说明
- 精准查询判断:增加了产品类型判断,避免影响站点内其他自定义文章类型的查询
- 保留用户排序:仅将特色产品排序前置,原选择的价格、销量等排序逻辑完全保留
- 数字排序更准确:WooCommerce的
_featured字段存储为数字(1=特色,0=非特色),用meta_value_num比meta_value排序更可靠 - 适配内置排序:覆盖了WooCommerce默认的所有排序选项,可根据需求扩展自定义排序的处理
使用注意
- 将代码添加到当前主题的
functions.php文件,或使用代码片段插件(如Code Snippets)避免主题更新丢失 - 测试所有排序选项,确认特色产品始终出现在对应排序结果的顶部
- 若有第三方插件添加的自定义排序,需在
switch语句中补充对应case处理
内容的提问来源于stack exchange,提问作者Filippo
相关产品推荐
相关产品推荐

