WordPress中WP_Query按自定义Metabox日期排序问题求助
解决WordPress自定义Metabox日期排序问题
首先得指出你代码里的核心问题:你把$new_date_format当成了meta_key的值,但实际上meta_key应该是你存在数据库里的自定义字段名称;而且你是在循环里才给$new_date_format赋值,在WP_Query执行的时候这个变量根本是空的,自然没法实现排序。
下面给你两种可行的解决方案,按需选择:
方案一:保存帖子时自动存储可排序的日期格式(推荐,查询效率更高)
这个思路是在用户发布/更新帖子时,自动把Metabox里的日期转换成Y-m-d格式,存成一个新的自定义字段,之后查询时直接用这个字段排序就行。
先添加保存钩子的代码(可以放到主题的functions.php里):
// 保存帖子时自动生成格式化后的活动日期 add_action('save_post', 'save_formatted_event_date'); function save_formatted_event_date($post_id) { // 跳过自动保存和修订版,避免重复执行 if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return; if (wp_is_post_revision($post_id)) return; // 获取Metabox里的原始日期 $raw_event_date = vp_metabox('event_date.date_event'); if (!empty($raw_event_date)) { $timestamp = strtotime($raw_event_date); // 转换成Y-m-d格式 $formatted_date = date('Y-m-d', $timestamp); // 把格式化后的日期存到新的自定义字段 update_post_meta($post_id, 'event_formatted_date', $formatted_date); } else { // 如果没有填写日期,删除这个字段 delete_post_meta($post_id, 'event_formatted_date'); } }
然后修改你的查询代码:
// 构建查询参数,按格式化后的日期升序,并且只显示今日及以后的活动 $args = array( 'meta_key' => 'event_formatted_date', 'orderby' => 'meta_value', // Y-m-d格式的字符串排序和日期顺序一致,用meta_value即可 'order' => 'ASC', // 升序是从旧到新,要是想从今日到最新(新的在前)就改成DESC 'posts_per_page' => 4, // 筛选今日及以后的活动,不需要的话可以删掉这段meta_query 'meta_query' => array( array( 'key' => 'event_formatted_date', 'value' => date('Y-m-d'), 'compare' => '>=', 'type' => 'DATE' ) ) ); $query = new WP_Query($args); if($query->have_posts()): while ($query->have_posts()) : $query->the_post(); // 这里可以直接获取提前存好的格式化日期,也可以继续用原来的方式获取 $new_date_format = get_post_meta(get_the_ID(), 'event_formatted_date', true); // 你的帖子内容输出逻辑... endwhile; // 记得重置查询 wp_reset_postdata(); endif;
⚠️ 注意:对于已经发布的旧帖子,你需要重新编辑保存一下,这个格式化后的日期字段才会被生成;如果帖子数量多,可以写个批量更新脚本一次性处理,或者用数据库批量插入的方式。
方案二:直接使用原始存储的日期值(如果原始格式支持排序)
先确认你的vp_metabox('event_date.date_event')在数据库里存储的格式是什么:
- 如果是时间戳:直接用这个字段作为
meta_key,排序用meta_value_num - 如果是Y-m-d格式的字符串:排序用
meta_value就行,因为这种格式的字符串排序和日期顺序是一致的
首先你需要确认这个自定义字段的实际键名(VP Metabox的子字段可能会把键名转成event_date_date_event这种格式,你可以在数据库的wp_postmeta表里查一下,或者用get_post_meta(get_the_ID(), '', true)输出所有字段看一下)。
假设实际键名是event_date_date_event,且存储的是Y-m-d格式,查询代码如下:
$args = array( 'meta_key' => 'event_date_date_event', 'orderby' => 'meta_value', 'order' => 'ASC', 'posts_per_page' => 4, 'meta_query' => array( array( 'key' => 'event_date_date_event', 'value' => date('Y-m-d'), 'compare' => '>=', 'type' => 'DATE' ) ) ); $query = new WP_Query($args); // 后面的循环逻辑和你原来的一样 if($query->have_posts()): while ($query->have_posts()) : $query->the_post(); $timestamp = strtotime(vp_metabox('event_date.date_event')); $new_date_format = date('Y-m-d', $timestamp); // 输出内容... endwhile; wp_reset_postdata(); endif;
内容的提问来源于stack exchange,提问作者Powerballs
相关产品推荐
相关产品推荐

