WP DEVELOP

EP079. “搜索结果:Professors 卡片与 Events 摘要样式”

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

接上一讲,把 Professors 和 Events 的搜索结果从简单文字列表换成跟 single-program.php(教授卡片)、template-parts/content-event.php(首页事件卡片)视觉一致的自定义卡片样式。做法是直接从这两个现成的 PHP 模板里把 HTML 结构复制过来,再把里面的 PHP 逐一换成 JavaScript 表达式,同时给自定义 API 补上教授头像图、事件月份/日期/摘要这些前端要用的字段。


涉及文件

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

代码实现

inc/search-route.php:给 professor / event 结果补充字段

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

// professor 分支新增 image 字段(教授头像,裁切成 professorLandscape 尺寸)
'permalink' => get_the_permalink(),
'image' => get_the_post_thumbnail_url(0, 'professorLandscape')

// event 分支:在 array_push 之前先算好 $eventDate / $description,再新增 month / day / description 字段
$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);
}
// ...
'permalink' => get_the_permalink(),
'month' => $eventDate->format('M'),
'day' => $eventDate->format('d'),
'description' => $description

src/modules/Search.js:Professors 卡片(在 Professors 标题下方插入,替换掉原本占位的空 <h2>):

<h2 class="search-overlay__section-title">Professors</h2>
${results.professors.length ? '<ul class="professor-cards">' : `<p>No professors match that search.</p>`}
  ${results.professors
    .map(
      item => `
    <li class="professor-card__list-item">
      <a class="professor-card" href="${item.permalink}">
        <img class="professor-card__image" src="${item.image}">
        <span class="professor-card__name">${item.title}</span>
      </a>
    </li>
  `
    )
    .join("")}
${results.professors.length ? "</ul>" : ""}

Events 摘要卡片(在 Events 标题下方插入):

<h2 class="search-overlay__section-title">Events</h2>
${results.events.length ? "" : `<p>No events match that search. <a href="${universityData.root_url}/events">View all events</a></p>`}
  ${results.events
    .map(
      item => `
    <div class="event-summary">
      <a class="event-summary__date t-center" href="${item.permalink}">
        <span class="event-summary__month">${item.month}</span>
        <span class="event-summary__day">${item.day}</span>  
      </a>
      <div class="event-summary__content">
        <h5 class="event-summary__title headline headline--tiny"><a href="${item.permalink}">${item.title}</a></h5>
        <p>${item.description} <a href="${item.permalink}" class="nu gray">Learn more</a></p>
      </div>
    </div>
  `
    )
    .join("")}

关键改动点:

  • Professors 卡片直接照抄 single-program.php 里教授列表的 <li class="professor-card__list-item"> 结构,professor-cards<ul> class 用来触发对应 CSS(跟原本文字列表用的 link-list min-list 不一样)
  • Events 卡片直接照抄 template-parts/content-event.php 的结构;events 无结果的提示文案跟 programs/campuses 不同,用的是空字符串占位(因为 events 结构本身不需要 <ul> 开头标签,这只是当初写 CSS 时的写法差异,跟 WordPress/JS 逻辑无关)
  • $eventDateDateTime 包一层 get_field('event_date'),再用 ->format('M') / ->format('d') 取三字母月份缩写和日期数字——这段逻辑是直接从原本首页事件模板里复制过来的
  • Professors、Events 都没有 programs/campuses 那种「查看全部」链接,是因为网站没有 all-professors 页面(events 有 /events 页所以保留了链接)

[截图:前台搜索 overlay 里 Professors 卡片(含头像图)和 Events 摘要卡片(月份/日期/摘要)的实际展示效果]


Hook / Function 速查

名称类型用途
get_the_post_thumbnail_url($post_id, $size)WP 内建 function获取指定尺寸的特色图片 URL,0 代表当前循环的 post
get_field()ACF function读取 Advanced Custom Fields 自定义字段值
has_excerpt()WP 内建 function判断当前文章是否手写了摘要
get_the_excerpt()WP 内建 function获取手写摘要
wp_trim_words($text, $num)WP 内建 function没有手写摘要时,从正文截取前 N 个词作为兜底摘要
new DateTime()->format()PHP 内建类把日期字段格式化成指定格式(M=三字母月份,d=两位日期)

常见坑

  • Professors 头像图用的裁切尺寸是 professorLandscape,这个尺寸名是课程前面章节自己注册的自定义图片尺寸,如果尺寸名对不上,get_the_post_thumbnail_url() 会拿到原图或空值
  • Events 摘要要先判断 has_excerpt(),没有手写摘要才用 wp_trim_words() 截正文兜底,不能直接无脑用 get_the_content(),否则长文章的搜索结果卡片会被撑爆

延伸 / 后续讲座会用到

目前搜索还只是关键词匹配(标题/正文含有搜索词才会出现),下一讲要做「按关联关系搜索」——比如搜索 biology 时,要能连带搜出关联到 biology 项目的教授和活动,即使教授/活动本身的标题和内容里没有 biology 这个词。


Sources

Udemy:

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