如何让WooCommerce [products]短代码按指定产品ID顺序排序?
解决WooCommerce [products]短代码按传入ID顺序排序的问题
我之前刚好碰到过一模一样的需求,其实不用绕远路重新写WP_Query,WooCommerce本身就提供了专门的过滤器来修改产品短代码的查询参数,刚好能解决这个排序问题。
具体解决方案
你只需要把下面这段代码添加到你的主题functions.php文件,或者自定义功能插件里:
add_filter( 'woocommerce_shortcode_products_query', 'custom_products_shortcode_order_by_post_in', 10, 3 ); function custom_products_shortcode_order_by_post_in( $query_args, $atts, $loop_name ) { // 仅针对传入了ids参数的[products]短代码生效 if ( ! empty( $atts['ids'] ) && 'products' === $loop_name ) { // 将逗号分隔的ID字符串转为整数数组 $product_ids = array_map( 'intval', explode( ',', $atts['ids'] ) ); // 设置查询按传入的ID顺序排列 $query_args['post__in'] = $product_ids; $query_args['orderby'] = 'post__in'; // 确保排序方向为正序(匹配传入的ID顺序) $query_args['order'] = 'ASC'; } return $query_args; }
代码解释
- 这个
woocommerce_shortcode_products_query过滤器是WooCommerce专门为产品短代码设计的,用来修改底层的WP_Query参数,它接收三个参数:$query_args:当前短代码的查询参数数组$atts:你传入短代码的所有属性(比如ids、columns这些)$loop_name:当前短代码的标识,这里我们只针对products短代码
- 我们先判断是否传入了
ids参数,避免影响其他没有指定ID的产品短代码 - 将传入的ID字符串转成整数数组,赋值给
post__in,同时设置orderby为post__in——这是WP_Query的特殊排序规则,会严格按照post__in数组里的ID顺序返回内容 - 最后设置
order为ASC,确保排序方向和我们传入的ID顺序一致(如果设为DESC会反转顺序)
可选:更灵活的生效方式
如果你不想让所有带ids参数的[products]短代码都生效,可以加个自定义开关属性:
- 使用短代码时加上自定义属性:
[products ids="1,2,3,4,5" columns="3" orderby_post_in="true"]
- 修改代码里的判断条件:
if ( ! empty( $atts['ids'] ) && 'products' === $loop_name && isset( $atts['orderby_post_in'] ) && 'true' === $atts['orderby_post_in'] ) {
这样只有明确加上orderby_post_in="true"的短代码才会按ID顺序排序,不会影响其他场景。
添加完代码后,你再执行原来的do_shortcode调用,返回的产品列表就会严格按照你传入的ID顺序排列了。
内容的提问来源于stack exchange,提问作者Diego Somar




