在RichText工具栏中,链接格式使用位于“/wp/v2/search”(参见
/wp/v2/search
)的搜索REST API端点。因此,尽管该端点没有提供专门用于过滤响应的挂钩,但是您可以使用
rest_post_dispatch
添加自定义链接到通过
/wp/v2/search
返回的搜索结果。
因此,在下面的示例中,我检查路由是否为
/wp/v2/search
,如果是,则添加(自定义)文章类型的归档链接。还请注意,您应该提供包含
此处所述项(LinkControl组件使用的内容)的数组。
基本示例
仅包括一个帖子类型,其中其名称与搜索关键字完全匹配。
add_filter( 'rest_post_dispatch', 'so_62472641', 10, 3 );
function so_62472641( $response, $server, $request ) {
if ( 'post' !== $request->get_param( 'type' ) ||
'/wp/v2/search' !== $request->get_route() ) {
return $response;
}
$search = $request->get_param( 'search' );
if ( ! $post_type = get_post_type_object( $search ) ) {
return $response;
}
if ( $url = get_post_type_archive_link( $search ) ) {
$data = (array) $response->get_data();
$data[] = [
'id' => 'post_type-' . $search,
'type' => 'Post Type Archive',
'title' => $post_type->label,
'url' => $url,
];
$response->set_data( $data );
}
return $response;
}
扩展示例
包括所有帖子类型,其中名称/标签与搜索关键字匹配。
add_filter( 'rest_post_dispatch', 'so_62472641', 10, 3 );
function so_62472641( $response, $server, $request ) {
if ( 'post' !== $request->get_param( 'type' ) ||
'/wp/v2/search' !== $request->get_route() ) {
return $response;
}
$search = $request->get_param( 'search' );
$post_types = get_post_types( [], 'objects' );
$extra_data = [];
foreach ( $post_types as $obj ) {
if ( $search === $obj->name ||
false !== stripos( "{$obj->name} {$obj->label} {$obj->labels->singular_name}", $search )
) {
if ( $url = get_post_type_archive_link( $obj->name ) ) {
$extra_data[] = [
'id' => 'post_type-' . $obj->name,
'type' => 'Post Type Archive',
'title' => $obj->label,
'url' => $url,
];
}
}
}
if ( ! empty( $extra_data ) ) {
$response->set_data( array_merge( (array) $response->get_data(), $extra_data ) );
}
return $response;
}
第二个示例的样本输出
![第二个示例的样本输出](https://istack.dev59.com/L20A4.webp)
注意:以上是真实响应的屏幕截图,但我故意(通过 PHP)将域名更改为example.com
(即实际域名不同)。
并且这两个示例都经过尝试和测试,在 WordPress 5.5.1(撰写时的最新版本)上运行正常。如果你想的话,还可以排除默认的post
文章类型。
附加说明
It should be noted that the examples do not take into account the pagination, which means, if there were 10 post types that matched the search keyword, then they would always be included in the response (on page 1, 2, 3, etc.). So you might want to just use the first example because at least it always includes at most 1 post type only. However, with the second example, you can actually limit the $extra_data
to, say, 5 items (per page - but it's up to you on how to distribute the items per page).
You can also use a custom search handler class, e.g. one that extends the default class (WP_REST_Post_Search_Handler
) and use the wp_rest_search_handlers
hook to add your class to the list. Here's a very basic example...
In your-class.php
:
class My_WP_REST_Post_Search_Handler extends WP_REST_Post_Search_Handler {
}
return new My_WP_REST_Post_Search_Handler;
In the theme's functions.php
file or somewhere in your plugin:
add_filter( 'wp_rest_search_handlers', 'my_wp_rest_search_handlers' );
function my_wp_rest_search_handlers( $search_handlers ) {
$search_handlers[] = include_once '/path/to/the/your-class.php';
return $search_handlers;
}