You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WordPress自定义文章类型产品按两个ACF价格字段排序

自定义文章类型按ACF价格(含促销价)排序解决方案

嘿,我明白你想要实现的效果:让自定义文章类型的产品按照「实际售卖价格」排序——也就是有促销价(price_sale)的用促销价排,没有的就用原价(price)排。你的现有查询参数没法直接搞定这个,因为WordPress默认的orderby不支持动态从两个meta字段里选一个作为排序依据,咱们得用点SQL技巧来实现。

下面是一步步的实现方法:

1. 调整WP_Query的基础参数

首先,你的meta_query不用强制同时匹配price和price_sale(毕竟不是所有产品都有促销价对吧)。我们只需要确保price字段存在,price_sale是可选的。调整后的参数如下:

$args = array(
    'post_type' => 'your_custom_post_type', // 替换成你的自定义文章类型slug
    'tax_query' => array( // 替换成你的分类筛选逻辑
        array(
            'taxonomy' => 'categories',
            'field'    => 'slug',
            'terms'    => 'sofas',
        ),
    ),
    'meta_query' => array(
        'relation' => 'OR',
        // 匹配有促销价的产品
        array(
            'key'     => 'price_sale',
            'compare' => 'EXISTS',
            'type'    => 'NUMERIC',
        ),
        // 匹配只有原价的产品(确保原价存在)
        array(
            'key'     => 'price',
            'compare' => 'EXISTS',
            'type'    => 'NUMERIC',
        ),
    ),
    // 先填一个占位的orderby,后面会用过滤器修改
    'orderby' => 'meta_value_num',
    'order' => 'ASC',
);

2. 用posts_orderby过滤器自定义排序逻辑

WordPress允许我们通过posts_orderby过滤器修改查询的排序SQL,这正是我们需要的。我们可以用SQL的CASE语句来动态选择排序的价格字段:

add_filter('posts_orderby', 'custom_price_sort_order', 10, 2);
function custom_price_sort_order($orderby, $query) {
    // 只针对我们的目标查询生效,别影响其他查询
    if (!isset($query->query['post_type']) || $query->query['post_type'] !== 'your_custom_post_type') {
        return $orderby;
    }

    global $wpdb;

    // 核心逻辑:如果有有效的price_sale,用它;否则用price,然后升序排列
    $orderby = "
        CASE
            WHEN (SELECT meta_value FROM {$wpdb->postmeta} WHERE post_id = {$wpdb->posts}.ID AND meta_key = 'price_sale') > 0
            THEN (SELECT meta_value FROM {$wpdb->postmeta} WHERE post_id = {$wpdb->posts}.ID AND meta_key = 'price_sale')
            ELSE (SELECT meta_value FROM {$wpdb->postmeta} WHERE post_id = {$wpdb->posts}.ID AND meta_key = 'price')
        END ASC
    ";

    return $orderby;
}

3. 执行查询并清理过滤器

执行查询后,记得移除这个过滤器,避免干扰后续的WordPress查询:

$products_query = new WP_Query($args);

// 移除过滤器,防止影响其他查询
remove_filter('posts_orderby', 'custom_price_sort_order');

// 循环输出结果
if ($products_query->have_posts()) {
    while ($products_query->have_posts()) {
        $products_query->the_post();
        $price = get_field('price');
        $sale_price = get_field('price_sale');
        $display_price = !empty($sale_price) && $sale_price > 0 ? $sale_price : $price;
        echo get_the_title() . ' - ' . $display_price . '$<br>';
    }
    wp_reset_postdata();
}

一些细节调整:

  • 如果你的price_sale字段允许为空字符串(而不是0),可以把CASE里的判断改成WHEN (SELECT meta_value FROM {$wpdb->postmeta} WHERE post_id = {$wpdb->posts}.ID AND meta_key = 'price_sale') != ''
  • 如果你想按降序排序,把END ASC改成END DESC就可以了

这样设置后,所有产品都会按照各自的实际售卖价格(促销价优先,原价兜底)升序排列,完全符合你想要的排序逻辑。

内容的提问来源于stack exchange,提问作者Plikard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:42:09