大家好!今天我们来聊聊 WordPress REST API 的 rest_post_query
过滤器,看看如何像个魔法师一样,修改 REST API 返回的文章查询结果。别怕,这玩意儿没那么神秘,咱们一步一步来,保证让你学会。
开场白:REST API 和文章查询的那些事儿
想象一下,WordPress 的 REST API 就像一个邮递员,专门负责传递信息。你问它:“嘿,邮递员,给我最近发布的 10 篇文章!” 它屁颠屁颠地跑到数据库里,把文章找出来,然后用 JSON 格式打包好,再给你送过来。
但是,有时候你可能对邮递员说:“等等!别急着送,我需要你先检查一下包裹,把标题里包含‘秘密’的文章过滤掉,或者把文章按照发布时间倒序排列。” 这时候,rest_post_query
过滤器就派上用场了。它就像一个中间人,允许你在邮递员(REST API)把文章送给你之前,先拦截一下,然后修改查询条件。
rest_post_query
过滤器:拯救世界的超级英雄
rest_post_query
过滤器本质上是一个钩子(Hook),它允许你在 REST API 处理文章查询之前,插入你自己的代码。它的作用是修改 $query
对象,这个 $query
对象包含了所有用于查询文章的参数,比如文章类型、状态、排序方式等等。
rest_post_query
过滤器的参数
rest_post_query
过滤器接收两个参数:
$query
: WP_Query 对象,包含了所有文章查询的参数。$request
: WP_REST_Request 对象,包含了客户端发送的请求信息,比如 URL 参数、请求方法等等。
实战演练:用 rest_post_query
过滤器做点儿有趣的事情
接下来,咱们通过几个具体的例子,来看看如何使用 rest_post_query
过滤器。
例子 1:只显示“秘密”分类下的文章
假设你只想让 REST API 返回“秘密”分类下的文章,怎么办呢?很简单,只需要在你的主题的 functions.php
文件或者自定义插件中添加以下代码:
<?php
/**
* 修改 REST API 文章查询,只显示“秘密”分类下的文章
*
* @param WP_Query $query WP_Query 对象.
* @param WP_REST_Request $request 请求对象.
* @return WP_Query
*/
function my_custom_rest_post_query( $query, $request ) {
// 获取请求的路由
$route = $request->get_route();
// 仅当请求是 /wp/v2/posts 时才应用修改
if ( '/wp/v2/posts' === $route ) {
// 获取“秘密”分类的 ID
$secret_category_id = get_cat_ID( '秘密' ); // 请确保你的分类名称是“秘密”
if ( $secret_category_id ) {
// 修改 WP_Query 对象,只查询“秘密”分类下的文章
$query->set( 'cat', $secret_category_id );
} else {
// 如果“秘密”分类不存在,可以输出一个错误信息
// error_log( '“秘密”分类不存在!' );
// 或者直接返回原始的查询对象,不进行修改
return $query;
}
}
return $query;
}
add_filter( 'rest_post_query', 'my_custom_rest_post_query', 10, 2 );
这段代码做了什么呢?
- 首先,我们定义了一个名为
my_custom_rest_post_query
的函数,这个函数接收$query
和$request
两个参数。 - 然后,我们检查请求的路由是否是
/wp/v2/posts
,确保只修改文章列表的查询。 - 接着,我们获取“秘密”分类的 ID。请注意,你需要将
'秘密'
替换成你实际的分类名称。 - 如果“秘密”分类存在,我们就修改
$query
对象,设置cat
参数为“秘密”分类的 ID。这样,REST API 就只会返回“秘密”分类下的文章了。 - 最后,我们使用
add_filter
函数将my_custom_rest_post_query
函数添加到rest_post_query
过滤器中。10
是优先级,2
是参数个数。
例子 2:按照标题长度排序文章
有时候,你可能想按照文章标题的长度来排序文章。这个稍微复杂一点,需要用到 posts_orderby
过滤器。
<?php
/**
* 修改 REST API 文章查询,按照标题长度排序文章
*
* @param WP_Query $query WP_Query 对象.
* @param WP_REST_Request $request 请求对象.
* @return WP_Query
*/
function my_custom_rest_post_query_title_length( $query, $request ) {
// 获取请求的路由
$route = $request->get_route();
// 仅当请求是 /wp/v2/posts 时才应用修改
if ( '/wp/v2/posts' === $route ) {
// 添加一个自定义的 orderby 参数
add_filter( 'posts_orderby', 'my_custom_posts_orderby', 10, 2 );
$query->set( 'orderby', 'title_length' );
}
return $query;
}
add_filter( 'rest_post_query', 'my_custom_rest_post_query_title_length', 10, 2 );
/**
* 自定义 posts_orderby 过滤器,实现按照标题长度排序
*
* @param string $orderby SQL ORDER BY 子句.
* @param WP_Query $query WP_Query 对象.
* @return string
*/
function my_custom_posts_orderby( $orderby, $query ) {
global $wpdb;
if ( 'title_length' === $query->get( 'orderby' ) ) {
$orderby = "LENGTH({$wpdb->posts}.post_title)";
}
return $orderby;
}
这段代码做了什么呢?
- 首先,我们定义了一个名为
my_custom_rest_post_query_title_length
的函数,这个函数接收$query
和$request
两个参数。 - 然后,我们检查请求的路由是否是
/wp/v2/posts
,确保只修改文章列表的查询。 - 接着,我们使用
add_filter
函数将my_custom_posts_orderby
函数添加到posts_orderby
过滤器中。 - 然后,我们设置
$query
对象的orderby
参数为'title_length'
。 - 在
my_custom_posts_orderby
函数中,我们判断$query
对象的orderby
参数是否是'title_length'
。如果是,我们就修改$orderby
变量,使用LENGTH({$wpdb->posts}.post_title)
来按照标题长度排序。
例子 3:根据自定义字段进行过滤
假设你有一个名为 _my_custom_field
的自定义字段,你想只显示这个字段的值为 secret
的文章。你可以这样做:
<?php
/**
* 修改 REST API 文章查询,根据自定义字段进行过滤
*
* @param WP_Query $query WP_Query 对象.
* @param WP_REST_Request $request 请求对象.
* @return WP_Query
*/
function my_custom_rest_post_query_meta( $query, $request ) {
// 获取请求的路由
$route = $request->get_route();
// 仅当请求是 /wp/v2/posts 时才应用修改
if ( '/wp/v2/posts' === $route ) {
$query->set( 'meta_key', '_my_custom_field' );
$query->set( 'meta_value', 'secret' );
$query->set( 'meta_compare', '=' ); // 可选,默认为 '='
}
return $query;
}
add_filter( 'rest_post_query', 'my_custom_rest_post_query_meta', 10, 2 );
这段代码很简单,就是设置 $query
对象的 meta_key
、meta_value
和 meta_compare
参数,来根据自定义字段进行过滤。
高级技巧:结合 URL 参数动态修改查询
有时候,你可能想根据 URL 参数来动态修改查询。比如,你希望用户可以通过 ?category=secret
来只显示“秘密”分类下的文章。
<?php
/**
* 修改 REST API 文章查询,根据 URL 参数动态修改查询
*
* @param WP_Query $query WP_Query 对象.
* @param WP_REST_Request $request 请求对象.
* @return WP_Query
*/
function my_custom_rest_post_query_url_params( $query, $request ) {
// 获取请求的路由
$route = $request->get_route();
// 仅当请求是 /wp/v2/posts 时才应用修改
if ( '/wp/v2/posts' === $route ) {
// 获取 URL 参数
$category = $request->get_param( 'category' );
if ( $category ) {
// 获取分类的 ID
$category_id = get_cat_ID( $category );
if ( $category_id ) {
// 修改 WP_Query 对象,只查询指定分类下的文章
$query->set( 'cat', $category_id );
}
}
}
return $query;
}
add_filter( 'rest_post_query', 'my_custom_rest_post_query_url_params', 10, 2 );
这段代码做了什么呢?
- 首先,我们使用
$request->get_param( 'category' )
获取 URL 中的category
参数。 - 如果
category
参数存在,我们就获取分类的 ID。 - 如果分类存在,我们就修改
$query
对象,设置cat
参数为分类的 ID。
表格总结:WP_Query
对象常用的参数
参数名 | 描述 | 例子 |
---|---|---|
post_type |
指定文章类型。默认值为 post 。 |
$query->set( 'post_type', 'page' ); // 只查询页面 |
post_status |
指定文章状态。默认值为 publish 。 |
$query->set( 'post_status', 'draft' ); // 只查询草稿状态的文章 |
posts_per_page |
每页显示的文章数量。默认值为 get_option( 'posts_per_page' ) 。 |
$query->set( 'posts_per_page', 5 ); // 每页显示 5 篇文章 |
orderby |
指定排序方式。常用的值有 date (发布时间)、title (标题)、ID (文章 ID)等等。 |
$query->set( 'orderby', 'title' ); // 按照标题排序 |
order |
指定排序顺序。ASC (升序)或 DESC (降序)。 |
$query->set( 'order', 'DESC' ); // 降序排列 |
cat |
指定分类 ID。 | $query->set( 'cat', 1 ); // 只查询 ID 为 1 的分类下的文章 |
tag_id |
指定标签 ID。 | $query->set( 'tag_id', 2 ); // 只查询 ID 为 2 的标签下的文章 |
s |
搜索关键词。 | $query->set( 's', '秘密' ); // 搜索包含“秘密”关键词的文章 |
meta_key |
自定义字段的键名。 | $query->set( 'meta_key', '_my_custom_field' ); // 指定自定义字段的键名为 _my_custom_field |
meta_value |
自定义字段的值。需要和 meta_key 配合使用。 |
$query->set( 'meta_value', 'secret' ); // 指定自定义字段的值为 secret |
meta_compare |
自定义字段的比较方式。常用的值有 = (等于)、!= (不等于)、> (大于)、< (小于)等等。 |
$query->set( 'meta_compare', '!=' ); // 指定自定义字段的值不等于 secret |
author |
指定作者ID。 | $query->set( 'author', 1 ); // 只查询ID为 1 的作者的文章 |
注意事项:安全第一!
在使用 rest_post_query
过滤器时,一定要注意安全问题。特别是当根据 URL 参数来修改查询时,要对用户输入进行严格的验证和过滤,防止 SQL 注入等安全漏洞。
总结:rest_post_query
过滤器,你的 REST API 好帮手
rest_post_query
过滤器是一个非常强大的工具,可以让你灵活地修改 REST API 的文章查询。通过它,你可以实现各种各样的自定义功能,比如只显示特定分类下的文章、按照标题长度排序文章、根据自定义字段进行过滤等等。只要你掌握了它的用法,就能像个魔法师一样,掌控 REST API 的文章查询!
希望今天的讲座对你有所帮助。记住,编程就像变魔术,多练习才能成为真正的魔法师!