WooCommerce如何按指定ID/SKU顺序在不同页面展示商品
WooCommerce 按指定ID/SKU顺序展示商品实现方案
orderby="post__in" 失效基本都是主题或第三方插件通过WooCommerce排序钩子篡改了短代码查询的排序规则,优先级覆盖了短代码传入的参数,不需要反复调整短代码参数,直接用下面的可落地方案即可,完全支持不同页面配置不同排序规则,不需要修改全局商品菜单排序。
方案1:修复原生products短代码按传入ID顺序输出
将下面的代码添加到当前子主题的functions.php文件,或者安装代码片段插件添加为全局代码片段:
// 强制products短代码按传入ids的顺序输出 add_filter( 'woocommerce_shortcode_products_query', 'force_products_shortcode_order_by_ids', 999, 3 ); function force_products_shortcode_order_by_ids( $query_args, $atts, $loop_name ) { if ( ! empty( $atts['ids'] ) ) { $query_args['orderby'] = 'post__in'; $query_args['order'] = 'ASC'; // 移除其他干扰排序的过滤器 remove_all_filters( 'posts_orderby', 10 ); } return $query_args; }
添加完成后直接使用原生短代码即可,不需要额外加orderby参数,系统会严格按照你传入的ID顺序输出商品:
- 页面1使用:
[products ids="1,3,2"],商品输出顺序为1→3→2 - 页面2使用:
[products ids="3,2,1"],商品输出顺序为3→2→1
方案2:按SKU指定顺序展示的自定义短代码
如果你更习惯用SKU而非商品ID控制排序,可以添加下面的代码实现自定义短代码:
// 新增支持按SKU顺序排序的商品短代码 add_shortcode( 'products_by_sku', 'custom_products_by_sku_order' ); function custom_products_by_sku_order( $atts ) { $atts = shortcode_atts( [ 'skus' => '', 'columns' => 4, 'limit' => -1, ], $atts ); if ( empty( $atts['skus'] ) ) return ''; $sku_list = array_map( 'trim', explode( ',', $atts['skus'] ) ); $products = wc_get_products( [ 'limit' => $atts['limit'], 'status' => 'publish', 'sku' => $sku_list, ] ); // 按传入的SKU顺序重排商品 $ordered_products = []; foreach ( $sku_list as $sku ) { foreach ( $products as $product ) { if ( $product->get_sku() === $sku ) { $ordered_products[] = $product; break; } } } ob_start(); woocommerce_product_loop_start( [ 'columns' => $atts['columns'] ] ); foreach ( $ordered_products as $product ) { $GLOBALS['product'] = $product; wc_get_template_part( 'content', 'product' ); } woocommerce_product_loop_end(); wc_reset_loop(); return ob_get_clean(); }
使用时直接按需要的顺序传入SKU即可,示例:[products_by_sku skus="SKU001,SKU003,SKU002" columns="3"]
上面的短代码会严格按照SKU001→SKU003→SKU002的顺序输出商品,可自由控制每行展示列数。
方案3:模板层自定义循环(适合嵌入自定义页面模板)
如果你需要在自定义页面模板中直接写商品展示逻辑,不需要依赖短代码,可以直接用下面的WP_Query代码,完全规避其他插件/主题的排序干扰:
// 按需要的顺序填写商品ID $custom_product_ids = [1,3,2]; $product_query = new WP_Query( [ 'post_type' => 'product', 'posts_per_page' => count( $custom_product_ids ), 'post__in' => $custom_product_ids, 'orderby' => 'post__in', 'post_status' => 'publish', ] ); if ( $product_query->have_posts() ) { woocommerce_product_loop_start(); while ( $product_query->have_posts() ) { $product_query->the_post(); wc_get_template_part( 'content', 'product' ); } woocommerce_product_loop_end(); wp_reset_postdata(); }
常见失效排查
- 添加完代码后请清空页面缓存、CDN缓存、WooCommerce商品瞬态缓存后再测试
- 短代码不要同时叠加
best_selling、on_sale、top_rated这类自带强制排序逻辑的参数,这类参数会覆盖ID/SKU的顺序规则 - 展示可变商品时传入父商品ID即可,不需要填写子变体ID
内容的提问来源于stack exchange,提问作者Jarxberg
相关产品推荐
相关产品推荐

