各位观众老爷们,大家好!我是今天的主讲人,咱们今天来聊聊WordPress REST API 中一个非常重要的过滤器:rest_prepare_post
。 相信大家在使用WordPress REST API 的时候,肯定遇到过这样的需求:想在API返回的数据中,添加一些WordPress默认没有提供的字段,或者想修改一下现有的字段内容。 那么,rest_prepare_post
就是解决这类问题的利器。
一、什么是 rest_prepare_post
过滤器?
首先,rest_prepare_post
是一个过滤器,它是WordPress在准备好文章(Post)类型的 REST API 响应数据之后,但在最终返回数据之前触发的。 简单来说,你可以把它理解为“数据加工厂”的最后一道工序,你可以在这里对数据进行“精装修”,添加你想要的“家具”,或者修改一些“装修风格”。
二、rest_prepare_post
过滤器的工作原理
当 WordPress REST API 需要返回一个文章类型的资源时(比如通过 /wp/v2/posts
获取文章列表,或者通过 /wp/v2/posts/{id}
获取单个文章),它会经过一系列的处理流程。 在这个流程的最后阶段,WordPress 会使用 apply_filters()
函数来应用 rest_prepare_post
过滤器。
apply_filters( 'rest_prepare_post', $response, $post, $request );
可以看到,这个过滤器接收三个参数:
$response
:一个WP_REST_Response
对象,包含了即将返回给客户端的全部数据。 你可以在这里添加、修改或删除数据。$post
:一个WP_Post
对象,代表当前正在处理的文章。 你可以从这个对象中获取文章的各种属性,比如标题、内容、作者等等。$request
:一个WP_REST_Request
对象,包含了客户端发送的请求信息,比如请求的参数、请求的头部等等。 你可以根据请求的信息来决定如何修改数据。
过滤器函数必须返回修改后的 $response
对象。
三、实战演练:添加自定义字段
废话不多说,直接上代码,演示如何在 REST API 响应中添加自定义字段。
场景1:添加文章阅读量
假设我们使用了一个插件或者自定义代码来记录文章的阅读量,并将阅读量存储在文章的自定义字段(meta field)中,字段名为 post_views
。现在我们想把这个阅读量添加到 REST API 的响应中。
<?php
/**
* 添加文章阅读量到 REST API 响应
*
* @param WP_REST_Response $response REST 响应对象.
* @param WP_Post $post 文章对象.
* @param WP_REST_Request $request 请求对象.
*
* @return WP_REST_Response 修改后的 REST 响应对象.
*/
function add_post_views_to_rest_response( $response, $post, $request ) {
// 获取文章阅读量
$post_views = get_post_meta( $post->ID, 'post_views', true );
// 确保阅读量是一个数字
$post_views = intval( $post_views );
// 将阅读量添加到响应数据中
$response->data['post_views'] = $post_views;
return $response;
}
add_filter( 'rest_prepare_post', 'add_post_views_to_rest_response', 10, 3 );
这段代码做了以下几件事:
- 定义了一个名为
add_post_views_to_rest_response
的函数,这个函数就是我们的过滤器函数。 - 使用
get_post_meta()
函数获取文章的阅读量。 - 使用
intval()
函数确保阅读量是一个整数。 - 将阅读量添加到
$response->data
数组中,键名为post_views
。 - 使用
add_filter()
函数将我们的过滤器函数添加到rest_prepare_post
过滤器中。10
是优先级,3
是参数个数。
现在,当你通过 REST API 获取文章数据时,你会发现响应中多了一个 post_views
字段,它的值就是文章的阅读量。
场景2:添加作者头像 URL
有时候,我们希望在文章的 REST API 响应中包含作者的头像 URL。 这也很简单,可以这样做:
<?php
/**
* 添加作者头像 URL 到 REST API 响应
*
* @param WP_REST_Response $response REST 响应对象.
* @param WP_Post $post 文章对象.
* @param WP_REST_Request $request 请求对象.
*
* @return WP_REST_Response 修改后的 REST 响应对象.
*/
function add_author_avatar_url_to_rest_response( $response, $post, $request ) {
// 获取作者 ID
$author_id = $post->post_author;
// 获取作者头像 URL
$author_avatar_url = get_avatar_url( $author_id, array( 'size' => 96 ) ); // 96 是头像大小
// 将作者头像 URL 添加到响应数据中
$response->data['author_avatar_url'] = $author_avatar_url;
return $response;
}
add_filter( 'rest_prepare_post', 'add_author_avatar_url_to_rest_response', 10, 3 );
这段代码与上面的例子类似,只是获取的数据不同,使用了 get_avatar_url()
函数来获取作者的头像 URL。
四、实战演练:修改现有字段
除了添加自定义字段,我们还可以使用 rest_prepare_post
过滤器来修改现有的字段。
场景:修改文章标题
假设我们想在 REST API 响应中,将文章标题加上一个前缀 "[Modified]"。
<?php
/**
* 修改文章标题
*
* @param WP_REST_Response $response REST 响应对象.
* @param WP_Post $post 文章对象.
* @param WP_REST_Request $request 请求对象.
*
* @return WP_REST_Response 修改后的 REST 响应对象.
*/
function modify_post_title( $response, $post, $request ) {
// 获取原始标题
$original_title = $response->data['title']['rendered'];
// 添加前缀
$modified_title = '[Modified] ' . $original_title;
// 修改标题
$response->data['title']['rendered'] = $modified_title;
return $response;
}
add_filter( 'rest_prepare_post', 'modify_post_title', 10, 3 );
注意,文章标题是一个嵌套的数组,我们需要修改 title['rendered']
字段。
五、根据请求参数进行条件修改
$request
对象包含了客户端发送的请求信息,我们可以根据这些信息来决定如何修改数据。
场景:只在请求包含 show_views=true
参数时才显示阅读量
<?php
/**
* 根据请求参数显示阅读量
*
* @param WP_REST_Response $response REST 响应对象.
* @param WP_Post $post 文章对象.
* @param WP_REST_Request $request 请求对象.
*
* @return WP_REST_Response 修改后的 REST 响应对象.
*/
function conditionally_add_post_views( $response, $post, $request ) {
// 获取请求参数
$params = $request->get_params();
// 检查是否包含 show_views 参数且值为 true
if ( isset( $params['show_views'] ) && $params['show_views'] === 'true' ) {
// 获取文章阅读量
$post_views = get_post_meta( $post->ID, 'post_views', true );
$post_views = intval( $post_views );
// 添加阅读量到响应数据中
$response->data['post_views'] = $post_views;
}
return $response;
}
add_filter( 'rest_prepare_post', 'conditionally_add_post_views', 10, 3 );
现在,只有当客户端发送 GET /wp/v2/posts?show_views=true
请求时,才会显示 post_views
字段。
六、处理不同类型的请求
$request
对象还可以区分不同的请求类型,比如 GET
、POST
、PUT
、DELETE
等等。 你可以使用 $request->get_method()
方法来获取请求类型。
七、代码组织和最佳实践
- 插件化: 将你的过滤器函数放在一个插件中,方便管理和维护。
- 代码注释: 编写清晰的代码注释,方便自己和他人理解代码。
- 错误处理: 考虑各种可能的错误情况,并进行适当的处理。
- 性能优化: 避免在过滤器函数中执行耗时的操作,以免影响 API 的性能。
- 使用命名空间: 为了避免与其他插件或主题的代码冲突,可以使用命名空间。
八、常见问题
- 过滤器不生效: 检查你的过滤器函数是否正确地添加到了
rest_prepare_post
过滤器中,以及优先级是否设置正确。 - 数据格式错误: 确保你添加的数据格式符合 REST API 的规范。
- 性能问题: 如果你的过滤器函数执行了耗时的操作,可能会导致 API 的性能下降。 尽量避免在过滤器函数中执行复杂的逻辑。
九、总结
rest_prepare_post
过滤器是一个非常强大的工具,它可以让你轻松地定制 WordPress REST API 的响应数据。 通过它可以添加自定义字段、修改现有字段,甚至可以根据请求参数进行条件修改。 掌握了 rest_prepare_post
过滤器,你就可以更加灵活地使用 WordPress REST API,满足各种各样的需求。
希望今天的分享对大家有所帮助,如果有什么问题,欢迎在评论区留言。 感谢大家的观看!
附:常用函数和对象
函数/对象 | 描述 | 示例 |
---|---|---|
get_post_meta() |
获取文章的自定义字段值。 | $post_views = get_post_meta( $post->ID, 'post_views', true ); |
get_avatar_url() |
获取用户的头像 URL。 | $author_avatar_url = get_avatar_url( $author_id, array( 'size' => 96 ) ); |
$response->data |
包含 REST API 响应数据的数组。 可以通过修改这个数组来添加、修改或删除数据。 | $response->data['post_views'] = $post_views; |
$post |
WP_Post 对象,代表当前正在处理的文章。 可以从中获取文章的各种属性。 |
$author_id = $post->post_author; |
$request |
WP_REST_Request 对象,包含了客户端发送的请求信息。 可以从中获取请求的参数、头部等等。 |
$params = $request->get_params(); |
$request->get_method() |
获取 HTTP 请求方法 (GET, POST, PUT, DELETE 等). | if ( 'POST' === $request->get_method() ) { // Only do something on POST requests } |
示例代码整合
<?php
/**
* 增强 REST API 文章响应.
*/
add_filter( 'rest_prepare_post', 'enhance_rest_api_post_response', 10, 3 );
function enhance_rest_api_post_response( $response, $post, $request ) {
// 1. 添加文章阅读量 (仅当请求包含 show_views=true 时)
$params = $request->get_params();
if ( isset( $params['show_views'] ) && $params['show_views'] === 'true' ) {
$post_views = get_post_meta( $post->ID, 'post_views', true );
$post_views = intval( $post_views );
$response->data['post_views'] = $post_views;
}
// 2. 添加作者头像 URL
$author_id = $post->post_author;
$author_avatar_url = get_avatar_url( $author_id, array( 'size' => 96 ) );
$response->data['author_avatar_url'] = $author_avatar_url;
// 3. 修改文章标题
$original_title = $response->data['title']['rendered'];
$modified_title = '[Enhanced] ' . $original_title;
$response->data['title']['rendered'] = $modified_title;
// 4. 添加自定义字段 "is_featured" (假设这个字段存在)
$is_featured = get_post_meta( $post->ID, 'is_featured', true );
$response->data['is_featured'] = (bool) $is_featured; // 转换为布尔值
// 5. 根据请求方法进行不同的操作 (例如,只在 GET 请求时添加某些字段)
if ( 'GET' === $request->get_method() ) {
$response->data['request_type'] = 'GET Request';
} else {
$response->data['request_type'] = 'Not a GET Request';
}
return $response;
}
这个整合的示例演示了如何在一个过滤器函数中完成多个任务,包括添加自定义字段、修改现有字段以及根据请求参数和请求方法进行条件修改。 记得把示例代码放到你的主题的 functions.php
文件或者一个自定义插件中。
最后,祝大家编程愉快,bug 永不相见!