如何修复代码实现hot-sale标签商品置顶并显示全部商品?
问题解决:将Hot-Sale商品置顶并显示所有商品
问题原因分析
你的代码仅显示带hot-sale标签的商品,核心问题有三点:
- 逻辑错误:先设置
post__not_in为hot商品ID,随后合并hot_product_ids和post__not_in(结果是重复的hot商品ID数组),导致post__in仅包含hot商品ID,自然只展示这类商品。 - 页面覆盖不全:原判断条件未包含商品搜索页(
is_product_search()),不符合需求中覆盖所有商品列表页的要求。 - 参数冲突:同时设置
post__in和post__not_in会触发WordPress查询的优先级冲突,进一步导致结果异常。
修正后的代码
function pre_get_posts_hot_product( $query ) { // 匹配前台主查询及所有商品列表类页面(含搜索页) if ( ! is_admin() && $query->is_main_query() && ( is_shop() || is_product_taxonomy() || is_product_category() || is_product_tag() || is_product_search() ) ) { // 克隆查询获取当前页面下的hot-sale商品ID $hot_query = clone $query; $hot_query->set( 'tax_query', array( array( 'taxonomy' => 'product_tag', 'field' => 'slug', 'terms' => 'hot-sale', 'operator' => 'IN', ), ) ); $hot_query->set( 'fields', 'ids' ); $hot_product_ids = $hot_query->get_posts(); // 克隆查询获取当前页面下的所有商品ID $all_query = clone $query; $all_query->set( 'fields', 'ids' ); $all_product_ids = $all_query->get_posts(); // 筛选出非hot-sale的商品ID $non_hot_product_ids = array_diff( $all_product_ids, $hot_product_ids ); // 合并数组:hot商品置顶,其余商品跟随 $sorted_product_ids = array_merge( $hot_product_ids, $non_hot_product_ids ); // 仅当有商品ID时修改查询参数 if ( ! empty( $sorted_product_ids ) ) { $query->set( 'post__in', $sorted_product_ids ); $query->set( 'orderby', 'post__in' ); } // 清空tax_query避免与原页面的分类/标签筛选冲突 $query->set( 'tax_query', '' ); } } add_action( 'pre_get_posts', 'pre_get_posts_hot_product', 9999 );
代码说明
- 页面覆盖完整:新增
is_product_search()判断,确保商品搜索页也生效。 - 正确的ID排序逻辑:通过克隆原查询分别获取hot商品和全量商品ID,再通过
array_diff分离非hot商品,最后合并成hot在前的数组。 - 避免参数冲突:仅设置
post__in和orderby参数,并清空tax_query,确保原页面的筛选条件(如分类、搜索关键词)仍能生效。
内容的提问来源于stack exchange,提问作者Adam Luper
相关产品推荐
相关产品推荐

