WP DEVELOP

EP077. “自定义路由扩展为多 post type 分组搜索”

首页 WordPress 开发课程 REST API 自定义 · EP077
约 11 分钟· #EP077#REST API 自定义
🔒 登录后可标记已读

这一讲把路由从「只查 professor」扩展成同时查 postpageprofessorprogramcampusevent 六种 post type,并且不是把结果混在一个数组里返回,而是按类型分组:generalInfo(post+page 合并)、professorsprogramscampusesevents 各自一个子数组。这是为了配合 search overlay 未来的三栏布局(第一栏 general info,第二栏 programs+professors,第三栏 campuses+events),让前端 JS 拿到数据时不用自己再去分类,直接用。

涉及文件

  • wp-content/themes/fictional-university-theme/inc/search-route.php (修改,universitySearchResults() 内部的查询、变量命名和 loop 逻辑)

代码实现

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

function universitySearchResults($data) {
  // 修改:$professors 改名为 $mainQuery,post_type 从单一 'professor' 改成多类型数组
  $mainQuery = new WP_Query(array(
    'post_type' => array('post', 'page', 'professor', 'program', 'campus', 'event'),
    's' => sanitize_text_field($data['term'])
  ));

  // 修改:$professorResults 改名为 $results,从「一个平铺数组」改成「按类型分组的关联数组」
  $results = array(
    'generalInfo' => array(),
    'professors' => array(),
    'programs' => array(),
    'events' => array(),
    'campuses' => array()
  );

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

    // 新增:按 get_post_type() 判断,把结果推进对应的子数组
    if (get_post_type() == 'post' OR get_post_type() == 'page') {
      array_push($results['generalInfo'], array(
        'title' => get_the_title(),
        'permalink' => get_the_permalink()
      ));
    }

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

    if (get_post_type() == 'program') {
      array_push($results['programs'], array(
        'title' => get_the_title(),
        'permalink' => get_the_permalink()
      ));
    }

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

    if (get_post_type() == 'event') {
      array_push($results['events'], array(
        'title' => get_the_title(),
        'permalink' => get_the_permalink()
      ));
    }

  }

  return $results;
}

要点:

  • WP_Querypost_type 参数原本传单一字符串 'professor',改成传数组 array('post', 'page', 'professor', 'program', 'campus', 'event') 就能一次查多种 post type,不需要发六次请求。
  • 之前的平铺数组 $professorResults(每个元素都是 title + permalink)不够用了,因为前端要按类型分栏显示。所以改成一个关联数组 $results,键是分组名(generalInfo/professors/programs/events/campuses),值是各自的空数组,等着在 loop 里被填充。
  • loop 里用 get_post_type()(不带参数,取当前正在循环的这篇文章的 post type)配合一串 if 判断,把结果 array_push 进对应的子数组。postpage 共用同一个 generalInfo 分组(用 OR 判断两种类型)。
  • 变量名从 $professors/$professorResults 改成了 $mainQuery/$results,因为查询和结果已经不再只跟 professor 有关。

[截图:浏览器访问 wp-json/university/v1/search?term=xxx,查看按 generalInfo/professors/programs/campuses/events 分组的 JSON 结果]

Hook / Function 速查

名称类型用途
get_post_type()WP 内建 function(返回值,无参数时取当前循环项)在 loop 里判断当前这一篇文章属于哪个 post type,用来决定推进哪个分组数组

常见坑

  • transcript 原文没有额外提到本讲新的报错或踩坑,主要是重构变量命名和分组逻辑本身容易绕;transcript 特别提醒改名时要小心:查询对象改名后($professors$mainQuery),loop 条件、the_post() 调用这两处也要跟着改,漏改一处就会报错或拿不到数据。

延伸 / 后续讲座会用到

下一讲开始把前端 search overlay 的 JavaScript 跟这个新建的 university/v1/search 路由对接起来,实现真正的三栏搜索结果展示(general info / programs+professors / campuses+events)——对应 COMPLETED_NOTE 目录里的 S16-前端-OVERLAY-串接自定义-API。

Sources

Udemy:

  • Become a WordPress Developer: Unlocking Power With Code — Section 15, EP077