EP078. “搜索结果改用自定义 API,重写三栏布局”
🔒 登录后可标记已读把前端搜索结果的渲染逻辑从「用 WordPress 内建 REST API、分别查 posts/pages 再手动合并」改成「用上一 Section 建好的自定义 university/v1/search 端点,一次请求拿到全部数据」。同时把结果区从简单的一栏标题列表改成三栏布局(General Information / Programs / Professors / Campuses / Events),并顺手给自定义 API 的 JSON 补上前端要用到的 postType、authorName 字段。这一讲先完成 General Information、Programs、Campuses 三块的输出,Professors 和 Events 的卡片/事件样式留到下一讲。
涉及文件
wp-content/themes/fictional-university-theme/src/modules/Search.js(修改)wp-content/themes/fictional-university-theme/inc/search-route.php(修改)
代码实现
src/modules/Search.js:getResults() 方法重写(旧的双请求 + win/then 合并逻辑整段删除,改成单次 $.getJSON 请求自定义端点):
// wp-content/themes/fictional-university-theme/src/modules/Search.js
getResults() {
$.getJSON(universityData.root_url + "/wp-json/university/v1/search?term=" + this.searchField.val(), results => {
this.resultsDiv.html(`
<div class="row">
<div class="one-third">
<h2 class="search-overlay__section-title">General Information</h2>
${results.generalInfo.length ? '<ul class="link-list min-list">' : "<p>No general information matches that search.</p>"}
${results.generalInfo.map(item => `<li><a href="${item.permalink}">${item.title}</a> ${item.postType == "post" ? `by ${item.authorName}` : ""}</li>`).join("")}
${results.generalInfo.length ? "</ul>" : ""}
</div>
<div class="one-third">
<h2 class="search-overlay__section-title">Programs</h2>
${results.programs.length ? '<ul class="link-list min-list">' : `<p>No programs match that search. <a href="${universityData.root_url}/programs">View all programs</a></p>`}
${results.programs.map(item => `<li><a href="${item.permalink}">${item.title}</a></li>`).join("")}
${results.programs.length ? "</ul>" : ""}
<h2 class="search-overlay__section-title">Professors</h2>
</div>
<div class="one-third">
<h2 class="search-overlay__section-title">Campuses</h2>
${results.campuses.length ? '<ul class="link-list min-list">' : `<p>No campuses match that search. <a href="${universityData.root_url}/campuses">View all campuses</a></p>`}
${results.campuses.map(item => `<li><a href="${item.permalink}">${item.title}</a></li>`).join("")}
${results.campuses.length ? "</ul>" : ""}
<h2 class="search-overlay__section-title">Events</h2>
</div>
</div>
`)
this.isSpinnerVisible = false
})
}
关键改动点:
- 用
$.getJSON(url, results => {...})单次请求代替原本$.when(...).then(...)的双请求合并写法,回调用 ES6 箭头函数(避免this被改写) - 结果整体用
class="row"+ 三个class="one-third"的div做三栏布局 - 数据来源从旧的
combinedResults数组改成读results.generalInfo/results.programs/results.campuses(对应自定义端点 JSON 里的分类数组) - 判断当前结果是否为博客文章时,字段名从内建 REST API 的
type改成自定义 JSON 里的postType;链接地址字段从内建的link改成自定义 JSON 里的permalink - 无结果时的提示文案对 Programs / Campuses 额外加了「View all XXX」链接,用模板字符串拼
${universityData.root_url}/programs,避免网站不在根目录时链接失效 - 每次渲染完结果,在模板字符串结束后加一行
this.isSpinnerVisible = false,让用户可以立刻发起下一次搜索
[截图:前台搜索 overlay 输入关键词后,展示 General Information / Programs / Campuses 三栏布局的结果]
inc/search-route.php:给 General Info 结果补充 postType、authorName 属性:
// wp-content/themes/fictional-university-theme/inc/search-route.php
// 新增:在 generalInfo 的关联数组里补上 postType 和 authorName
'permalink' => get_the_permalink(),
'postType' => get_post_type(),
'authorName' => get_the_author()
Hook / Function 速查
| 名称 | 类型 | 用途 |
|---|---|---|
$.getJSON(url, callback) | jQuery 方法 | 发一次 GET 请求并把响应 JSON 传入回调 |
get_post_type() | WP 内建 function | 获取当前循环post的文章类型 |
get_the_author() | WP 内建 function | 获取当前循环post的作者名 |
常见坑
- 自定义 API 返回的 JSON 结构跟 WordPress 内建 REST API 不一样:标题不是嵌套在
title.rendered里,而是直接一个title字段;链接字段名是自定义的permalink不是内建的link——照抄旧代码字段名会导致前端显示undefined postType、authorName这两个字段内建 REST API 没有,必须自己在search-route.php里手动加到返回的关联数组里,前端逻辑才拿得到
延伸 / 后续讲座会用到
Professors 和 Events 的自定义卡片/事件摘要样式,留到 EP079 继续完成。
Sources
Udemy:
- Become a WordPress Developer: Unlocking Power With Code — Section 16, EP078