如何使用WP_Query实现ACF事件日期字段按从今日开始的顺序排序展示
问题分析
你当前的代码未区分事件是否过期,直接对所有事件的event_start_date字段按数值升序排序,因此更早的过期事件会排在队列最前,和预期的「未来事件在前、过期事件在后,未来事件按时间从近到远排序」的逻辑不符。
如果你的event_start_date存储的是Y-m-d格式的字符串,使用meta_value_num排序也存在精度问题,数值排序仅适配存储为时间戳格式的日期字段。
解决方案
方案1:分两次查询合并结果(逻辑简单易维护)
这种方法通过两次独立查询分别获取未来事件和过期事件,再合并结果集,不需要写自定义SQL,兼容性更好:
// 获取当前日期,格式和存储的event_start_date保持一致 $current_date = date('Y-m-d'); // 第一次查询:未来/今日的事件,按日期升序排列(最近的在前) $future_events = new WP_Query( array( 'post_type' => 'eventdate', 'posts_per_page' => -1, 'meta_key' => 'event_start_date', 'orderby' => 'meta_value', 'order' => 'ASC', 'meta_type' => 'DATE', 'meta_query' => array( array( 'key' => 'event_start_date', 'value' => $current_date, 'compare' => '>=', 'type' => 'DATE' ) ) ) ); // 第二次查询:已过期的事件,按日期降序排列(最近过期的在前,可按需调整排序规则) $past_events = new WP_Query( array( 'post_type' => 'eventdate', 'posts_per_page' => -1, 'meta_key' => 'event_start_date', 'orderby' => 'meta_value', 'order' => 'DESC', 'meta_type' => 'DATE', 'meta_query' => array( array( 'key' => 'event_start_date', 'value' => $current_date, 'compare' => '<', 'type' => 'DATE' ) ) ) ); // 合并两个查询的结果,得到符合预期的事件列表 $the_query = new WP_Query(); $the_query->posts = array_merge( $future_events->posts, $past_events->posts ); $the_query->post_count = $future_events->post_count + $past_events->post_count;
按照你给出的示例事件,最终输出顺序就是2021-10-11、2021-10-15、2021-10-08,完全符合预期。
方案2:单次查询自定义排序(仅需一次数据库请求)
如果要减少数据库查询次数,可以通过posts_orderby过滤器自定义排序逻辑,用CASE WHEN语句给未来事件赋予更高的排序优先级:
function custom_event_orderby( $orderby ) { global $wpdb; $current_date = date('Y-m-d'); return "CASE WHEN {$wpdb->postmeta}.meta_value >= '{$current_date}' THEN 1 ELSE 2 END ASC, {$wpdb->postmeta}.meta_value ASC"; } add_filter( 'posts_orderby', 'custom_event_orderby' ); // 执行查询 $the_query = new WP_Query( array( 'post_type' => 'eventdate', 'posts_per_page' => -1, 'meta_key' => 'event_start_date', 'orderby' => 'meta_value', 'order' => 'ASC', 'meta_type' => 'DATE' ) ); // 查询完成后移除过滤器,避免影响站点其他查询逻辑 remove_filter( 'posts_orderby', 'custom_event_orderby' );
如果你的event_start_date存储的是时间戳格式,把上述代码中的日期格式替换为时间戳,meta_type对应改成NUMERIC即可正常运行。
内容的提问来源于stack exchange,提问作者Daro125
相关产品推荐
相关产品推荐

