EP034. “用 meta_key / orderby / meta_query 按日期排序并过滤过去的活动”
🔒 登录后可标记已读📌 并入的公告(原 EP033 "A Note About the WordPress Post Edit Screen"): 这是一篇纯文字公告,没有实际代码或操作。Brad 说明从 2021 年 7 月起,他已经把前面所有讲座里出现的后台编辑画面截图都更新成新版 WP Block Editor 的样子,但接下来的讲座不会再重新补录旧的编辑画面镜头;如果之后视频里的编辑画面跟自己本地看到的长得不太一样,不用担心,2021 年 7 月这套代码已经用最新版 WordPress 验证过没问题。另外提到课程后半段会有专门讲插件开发和新版 Gutenberg Block 类型开发的章节。
「Upcoming Events」列表一直是按文章的发布日期排序(WordPress 默认行为),但真正该排序的依据应该是 event_date(EP032 刚加的自定义字段)——谁最快要举办,谁排前面。这一讲学的是 WP_Query 更进阶的用法:用 orderby + meta_key 按自定义字段排序,用 meta_query 过滤掉已经过去的活动(event_date 小于今天的不显示)。
涉及文件
wp-content/themes/fictional-university-theme/front-page.php(修改:Upcoming Events 的WP_Query参数新增排序与过滤条件)
代码实现
// wp-content/themes/fictional-university-theme/front-page.php
// Upcoming Events 区块,WP_Query 前新增 $today 变量,查询参数新增 meta_key / orderby / order / meta_query:
<?php
$today = date('Ymd'); // 新增:今天的日期,格式要跟 ACF 字段的 Return Format 一致
$homepageEvents = new WP_Query(array(
'posts_per_page' => -1, // 临时改成 -1(全部返回),方便边写边肉眼核对排序结果,是本讲的实验设定
'post_type' => 'event',
'meta_key' => 'event_date', // 新增:告诉 WP 我们要按这个自定义字段排序/过滤
'orderby' => 'meta_value_num', // 新增:按 meta 值排序,数字用 _num 版本,不能只用 meta_value
'order' => 'ASC', // 新增:升序,让最快到来的活动排最前面
'meta_query' => array( // 新增:过滤条件
array(
'key' => 'event_date',
'compare' => '>=',
'value' => $today,
'type' => 'numeric'
)
)
));
while($homepageEvents->have_posts()) {
$homepageEvents->the_post(); ?>
<div class="event-summary">
<a class="event-summary__date t-center" href="#">
<span class="event-summary__month"><?php
$eventDate = new DateTime(get_field('event_date'));
echo $eventDate->format('M')
?></span>
<span class="event-summary__day"><?php echo $eventDate->format('d') ?></span>
</a>
<div class="event-summary__content">
<h5 class="event-summary__title headline headline--tiny"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h5>
<p><?php if (has_excerpt()) {
echo get_the_excerpt();
} else {
echo wp_trim_words(get_the_content(), 18);
} ?> <a href="<?php the_permalink(); ?>" class="nu gray">Learn more</a></p>
</div>
</div>
<?php }
?>
要点:
orderby默认是post_date(发布日期);改成title会按标题字母排(还能用order => ASC/DESC控制正序/倒序),改成rand会每次刷新随机排序。这些都是这一讲用来演示orderby用法的实验,最终定案是按自定义字段排序。- 要按自定义字段排序,必须搭配
meta_key指定字段名(event_date),orderby才设成meta_value或meta_value_num。日期是数字,要用meta_value_num,用文字版的meta_value排序结果会不对(比如 "20170629" 和 "201709" 这种字符串比较跟数字比较结果不同)。 meta_query是一个「数组套数组」的结构:外层数组可以放多个过滤条件(本讲只用了一个),每个条件是一个内层数组,包含key(字段名)、compare(比较符)、value(比较值)、type(值的类型,数字要写numeric)。$today = date('Ymd')用 PHP 内建date()函数生成跟 ACF 字段同样格式(Ymd)的今天日期字符串,才能正确跟event_date比较。posts_per_page => -1是这一讲为了方便边测试边观察排序效果而临时改的(-1 代表「返回全部符合条件的结果」),不是最终值,下一讲会改回 2。
Hook / Function 速查
| 名称 | 类型 | 用途 |
|---|---|---|
orderby | WP_Query 参数 | 控制排序依据:post_date(默认)、title、rand、meta_value、meta_value_num 等 |
order | WP_Query 参数 | ASC(升序)或 DESC(降序,默认) |
meta_key | WP_Query 参数 | 配合 orderby => meta_value(_num) 使用,指定要排序的自定义字段名 |
meta_query | WP_Query 参数 | 按自定义字段值筛选文章,值是「数组套数组」的结构(key/compare/value/type) |
date($format) | PHP 内建 function(非 WordPress) | 按指定格式返回当前日期字符串,本讲用 Ymd 跟 ACF 字段格式对齐 |
常见坑
- 按数字类型的自定义字段排序时,
orderby用了meta_value而不是meta_value_num,排序结果会不对(meta_value是给字母/文字排序设计的,日期这种数字必须用_num版本)。 meta_query里的value必须跟 ACF 字段的 Return Format 保持一致的字符串格式(这里是Ymd),否则比较不会得到预期结果。posts_per_page => -1只是本讲为了方便肉眼核对排序效果而设的实验值,不是最终生产设定,下一讲会改回2。
延伸 / 后续讲座会用到
下一讲 EP035 会把这套排序 + 过滤逻辑,从「每次手写一个新的 WP_Query」升级成用 pre_get_posts 挂到 events 归档页的默认查询上,减少重复代码,也顺便解决分页问题。
Sources
Udemy:
- Become a WordPress Developer: Unlocking Power With Code — Section 7, EP033, EP034