WP DEVELOP

EP083. “按关联关系搜索:完成 Events 与 Campuses,搜索 Overlay 收尾”

首页 WordPress 开发课程 前端 OVERLAY 串接自定义 API · EP083
约 12 分钟· #EP083#前端 OVERLAY 串接自定义 API
🔒 登录后可标记已读

这一讲把「按关联关系搜索」补完剩下两种内容类型,整个搜索 Overlay 功能到此完工:

  • Events:跟 Professor 关联方向一样(Event → 关联到 Program),所以直接把上一讲那个查询的 post_type 从只查 professor 扩展成同时查 array('professor', 'event'),几乎是顺手就做完的
  • Campuses:关联方向是反过来的(Program 关联到 Campus,不是 Campus 关联到 Program),所以不需要新建查询,直接在主查询循环到 Program 时,用 get_field() 读出它关联的 Campus 顺手 push 进结果就行

涉及文件

  • wp-content/themes/fictional-university-theme/inc/search-route.php (修改)

代码实现

扩展关联查询同时覆盖 Professor 和 Eventpost_type 从字符串改成数组,while 循环里新增 event 分支,并复用 EP079 写好的 month/day/description 计算逻辑):

// wp-content/themes/fictional-university-theme/inc/search-route.php

$programRelationshipQuery = new WP_Query(array(
  'post_type' => array('professor', 'event'), // 修改:从 'professor' 扩展成数组
  'meta_query' => $programsMetaQuery
));

while ($programRelationshipQuery->have_posts()) {
  $programRelationshipQuery->the_post();

  // 新增:event 分支,逻辑跟主查询里的 event 分支一致
  if (get_post_type() == 'event') {
    $eventDate = new DateTime(get_field('event_date'));
    $description = null;
    if (has_excerpt()) {
      $description = get_the_excerpt();
    } else {
      $description = wp_trim_words(get_the_content(), 18);
    }

    array_push($results['events'], array(
      'title' => get_the_title(),
      'permalink' => get_the_permalink(),
      'month' => $eventDate->format('M'),
      'day' => $eventDate->format('d'),
      'description' => $description
    ));
  }

  if (get_post_type() == 'professor') {
    array_push($results['professors'], array(
      'title' => get_the_title(),
      'permalink' => get_the_permalink(),
      'image' => get_the_post_thumbnail_url(0, 'professorLandscape')
    ));
  }
}

$results['professors'] = array_values(array_unique($results['professors'], SORT_REGULAR));
// 新增:events 也要去重
$results['events'] = array_values(array_unique($results['events'], SORT_REGULAR));

Campus:在主查询循环到 Program 分支时,顺手读出关联的 Campus(关联字段 related_campus 虽然命名是单数,实际存的是数组):

// wp-content/themes/fictional-university-theme/inc/search-route.php
// 在主查询 while 循环、program 分支内新增:

$relatedCampuses = get_field('related_campus');

if ($relatedCampuses) {
  foreach ($relatedCampuses as $campus) {
    array_push($results['campuses'], array(
      'title' => get_the_title($campus),
      'permalink' => get_the_permalink($campus)
    ));
  }
}

关键改动点:

  • Event 之所以能直接扩展现有的关联查询,是因为它和 Professor 一样,关联方向都是「自己身上有个字段指向 Program」,所以同一个 meta_query(按 related_programs 关联字段过滤)对两种文章类型都成立,只要把 post_type 从字符串换成数组即可
  • Campus 的关联方向相反:不是 Campus 指向 Program,而是 Program 指向 Campus(作者解释这是因为项目可能有几十上百个,但校区通常只有几个,反过来存更好维护)。既然当前循环到的就是命中的 Program 本身,直接 get_field('related_campus') 就能拿到它关联的校区,不需要额外发起一次 WP_Query
  • get_the_title($campus) / get_the_permalink($campus) 要显式传入 $campus(关联字段返回的是校区的文章对象),因为当前循环上下文里 WordPress 认为「当前文章」是这个 Program,不传参数的话拿到的会是 Program 自己的标题和链接,而不是校区的
  • Campus 的 foreach 外面包了一层 if ($relatedCampuses),因为 related_campus 字段允许留空,没有关联校区时 get_field() 会返回空值/false,直接 foreach 会报错

[截图:前台搜索 overlay 完整效果,General Information / Programs / Professors / Campuses / Events 五个分组都通过关联关系正确显示结果]


Hook / Function 速查

名称类型用途
get_the_title($post) / get_the_permalink($post)WP 内建 function显式传入文章对象/ID,获取指定文章(而非当前循环文章)的标题/链接

常见坑

  • Campus 关联字段 related_campus 命名是单数,但实际存的是数组(可以关联多个校区)——遍历前要留意这一点,直接当成单个值用会出错
  • get_the_title() / get_the_permalink() 不传参数——在 Program 的循环上下文里调用这两个函数不传 $campus 参数,拿到的会是 Program 自己的标题和链接,不是校区的,很容易忽略这个细节
  • Events 关联查询新增后忘记同步补上 array_unique 去重——跟 Professors 一样,Event 也可能同时被关键词查询和关联查询命中,产生重复

延伸 / 后续讲座会用到

到这一讲,搜索 Overlay 功能全部完工。下一讲(EP084)会提供一个可选的 jQuery-free 版本 Search.js,用原生 JS + Axios 重写同样的功能,纯属技术选型的补充说明。再往后课程会转向用户权限与角色系统。


Sources

Udemy:

  • Become a WordPress Developer: Unlocking Power With Code — Section 16, EP083