WP DEVELOP

EP073. “给已有 REST 字段加自定义属性(register_rest_field)”

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

之前 Section 13-14 是从 JS 那头「消费」wp/v2/posts 这类内建 REST API,这一讲开始换个角度:从 PHP 这头「定制」REST API 输出的原始 JSON。需求场景是 search overlay 里希望博客文章结果显示成「标题 by 作者名」,但 wp/v2/posts 默认只给作者的 ID(author 字段),没有人类可读的名字。这一讲用 register_rest_field()post 类型的 REST 输出里加一个新字段 authorName,值来自 get_the_author(),然后在 Search.js 里用这个新字段拼出「by 作者名」文字。

涉及文件

  • wp-content/themes/fictional-university-theme/functions.php (修改,加在文件最开头)
  • wp-content/themes/fictional-university-theme/src/modules/Search.js (修改,getResults() 方法里的模板字符串)

代码实现

functions.php 最开头新增(放在 <?php 后第一行):

<?php

// 新增:给 wp/v2/posts 的 REST 输出加一个 authorName 字段
function university_custom_rest() {
  register_rest_field('post', 'authorName', array(
    'get_callback' => function() {return get_the_author();}
  ));
}

add_action('rest_api_init', 'university_custom_rest');

Search.jsgetResults() 方法内,拼 HTML 的那一行改成用三元运算符判断,只有博客文章(type == "post")才显示「by 作者名」:

// src/modules/Search.js(getResults() 方法内,模板字符串片段)

${combinedResults.map(item => `<li><a href="${item.link}">${item.title.rendered}</a> ${item.type == "post" ? `by ${item.authorName}` : ""}</li>`).join("")}

要点:

  • register_rest_field($post_type, $field_name, $args) 三个参数:第一个是要定制的 post type(postpage,也可以是自定义 post type),第二个是新字段名(自己取,这里叫 authorName),第三个是数组,本讲只用了 get_callback
  • get_callback 是一个匿名函数,函数返回什么,这个新字段的值就是什么——可以是任何 PHP 能算出来的东西(ACF 字段值、裁切过的图片 URL、甚至一个自定义查询的结果都行),返回值最终会被转成 JSON。
  • 这个改动要挂在 rest_api_init 这个 hook 上,不是 init
  • 因为 page 这个 post type 没有注册 authorName 字段,所以 JS 那边如果不加判断,搜索结果里的页面会显示成「by undefined」。这就是为什么 Search.js 里用 item.type == "post" ? ... : "" 的三元表达式做条件判断——模板字符串里不能直接写 if,只能用三元运算符代替。

[截图:浏览器直接访问 wp-json/wp/v2/posts,查看 JSON 响应里新增的 authorName 字段]

Hook / Function 速查

名称类型用途
register_rest_field($post_type, $field_name, $args)WP 内建 function给指定 post type 的 REST API 输出追加一个自定义字段
rest_api_initWP hookREST API 初始化时触发,定制 REST 输出要挂在这个 hook 上(不是 init
get_the_author()WP 内建 function(返回值)返回当前文章作者的人类可读昵称

常见坑

  • 只给 post 类型注册了 authorName 字段,page 类型没有这个字段,如果 JS 不做类型判断直接拼 by ${item.authorName},页面类型的搜索结果会显示「by undefined」。

延伸 / 后续讲座会用到

下一讲(EP074)不再是修改已有的 REST 输出,而是从零建一个完全自定义的 REST 路由(university/v1/search),用来实现真正的跨内容类型搜索——因为 WordPress 内建搜索逻辑不认识自定义字段和 post 之间的关系(比如 program 和 professor 的关联),搜不到这些内容。

Sources

Udemy:

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