WP DEVELOP

EP034. “用 meta_key / orderby / meta_query 按日期排序并过滤过去的活动”

首页 WordPress 开发课程 CUSTOM POST TYPE 入门 · EP034
约 13 分钟· #EP034#CUSTOM POST TYPE 入门
🔒 登录后可标记已读

📌 并入的公告(原 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_valuemeta_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 速查

名称类型用途
orderbyWP_Query 参数控制排序依据:post_date(默认)、titlerandmeta_valuemeta_value_num
orderWP_Query 参数ASC(升序)或 DESC(降序,默认)
meta_keyWP_Query 参数配合 orderby => meta_value(_num) 使用,指定要排序的自定义字段名
meta_queryWP_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