boxybird / boxybird-wp-query-endpoint
使用单个REST API端点从WordPress数据库查询任何您想要的内容。
README
使用单个REST API端点从WordPress数据库查询任何您想要的内容。
简单来说,这个插件允许将url中的GET参数传递给WP_Query类作为$args
WP_Query参考:https://developer.wordpress.org/reference/classes/wp_query/
安装
克隆或下载插件,并在WordPress管理后台激活之前运行composer install。
使用示例
PHP
通常在WordPress主题或插件中,您会创建一个包含$arg的数组,并将其传递给WP_Query($args)构造函数。例如
<?php $args = [ 'post_type' => 'post', 'orderby' => 'title', 'posts_per_page' => 12, 'category__in' => [31, 12, 4], //... any other WP_Query args you want. ]; $query = new WP_Query($args); // loop through results in PHP file.
使用此插件,您可以从前端JavaScript传递相同的参数
纯JS
const url = 'https://your-site.com/wp-json/boxybird/wp-query/v1/args?post_type=post&orderby=title&posts_per_page=12&category__in[]=31&category__in[]=12&category__in[]=4' fetch(url) .then(res => res.json()) .then(data => { console.log(data) })
jQuery
const params = jQuery.param({ post_type: 'post', orderby: 'title', posts_per_page: 12, category__in: [31, 12, 4], //... any other WP_Query args you want. }); jQuery.get(`https:/your-site.com/wp-json/boxybird/wp-query/v1/args?${params}`).done((data) => { console.log(data); });
钩子
以下示例将使用一个假设的网站,该网站具有'movie' post_type。
格式化JSON响应
默认情况下,WP_Query将返回来自wp_posts表的原始行。如下所示
{
"success": true,
"data": [
{
"ID": 569,
"post_author": "1",
"post_date": "2020-11-23 00:17:16",
"post_date_gmt": "2020-11-23 00:17:16",
"post_content": "An eclectic foursome of aspiring teenage witches get more than they bargained for as they lean into their newfound powers.",
"post_title": "The Craft: Legacy",
"post_excerpt": "",
"post_status": "publish",
"comment_status": "closed",
"ping_status": "closed",
"post_password": "",
"post_name": "the-craft-legacy",
"to_ping": "",
"pinged": "",
"post_modified": "2020-11-23 00:17:16",
"post_modified_gmt": "2020-11-23 00:17:16",
"post_content_filtered": "",
"post_parent": 0,
"guid": "https://wp-query.andrewrhyand.com/movies/the-craft-legacy",
"menu_order": 0,
"post_type": "movie",
"post_mime_type": "",
"comment_count": "0",
"filter": "raw"
},
{
"ID": 567,
"post_author": "1",
"post_date": "2020-11-23 00:17:16",
"...and so on"
}
]
}
上面的内容在某些情况下可能很有用,但更常见的情况是您可能想要格式化JSON响应。这是执行此操作的过滤器
add_filter('boxybird/query/format-response', function (WP_Query $query) { // do something with $query and return. });
以下是如何使用该过滤器的示例
add_filter('boxybird/query/format-response', function (WP_Query $query) { // Assign queried 'post_type' $post_type = strtolower($query->query_vars['post_type']); // If it's a 'movie' post_type, format like this: if ($post_type === 'movie') { return array_map(function ($movie) { return [ 'id' => $movie->ID, 'title' => get_the_title($movie->ID), 'description' => get_the_content(null, false, $movie->ID), 'link' => get_the_permalink($movie->ID), 'genres' => array_map(function ($term) { return $term->name; }, get_the_terms($movie->ID, 'genre')), 'details' => array_map(function ($detail) { return $detail[0]; }, get_post_meta($movie->ID)), 'description' => [ 'short' => wp_trim_words(get_the_content(null, false, $movie->ID), 10), 'long' => wp_trim_words(get_the_content(null, false, $movie->ID), 75), ], 'images' => [ 'full' => get_the_post_thumbnail_url($movie->ID, 'full'), 'medium' => get_the_post_thumbnail_url($movie->ID, 'medium'), 'thumbnail' => get_the_post_thumbnail_url($movie->ID, 'thumbnail'), ], ]; }, $query->posts); } // If it's a 'post' post_type, format like this: if ($post_type === 'post') { return array_map(function ($post) { return [ 'id' => $post->ID, 'title' => get_the_title($post->ID), 'content' => get_the_content(null, false, $post->ID), 'link' => get_the_permalink($post->ID), ]; }, $query->posts); } // If it's any other post_type, format like this: return array_map(function ($post) { return [ 'id' => $post->ID, 'title' => get_the_title($post->ID), ]; }, $query->posts); });
关注上面的'movie' post_type,这将是一个自定义格式的响应
{
"success": true,
"data": [
{
"id": 553,
"title": "Dark Phoenix",
"description": "The X-Men face their most formidable and powerful foe when one of their own, Jean Grey, starts to spiral out of control. During a rescue mission in outer space, Jean is nearly killed when she's hit by a mysterious cosmic force. Once she returns home, this force not only makes her infinitely more powerful, but far more unstable. The X-Men must now band together to save her soul and battle aliens that want to use Grey's new abilities to rule the galaxy.",
"link": "https://wp-query.andrewrhyand.com/movies/dark-phoenix",
"genres": [
"Drama",
"Horror",
"Thriller"
],
"details": {
"budget": "200000000",
"status": "Released",
"tmdb_id": "320288",
"imdb_id": "tt6565702",
"revenue": "252442974",
"runtime": "114",
"tagline": "X-Men Dark Phoenix",
"homepage": "http://darkphoenix.com",
"popularity": "122.285",
"vote_count": "4063",
"vote_average": "61%",
"release_date": "Jun 05, 2019",
"_thumbnail_id": "554"
},
"short_description": {
"short": "The X-Men face their most formidable and powerful foe when…",
"long": "The X-Men face their most formidable and powerful foe when one of their own, Jean Grey, starts to spiral out of control. During a rescue mission in outer space, Jean is nearly killed when she's hit by a mysterious cosmic force. Once she returns home, this force not only makes her infinitely more powerful, but far more unstable. The X-Men must now band together to save her soul and battle aliens that want to use…"
},
"images": {
"full": "https://wp-query.andrewrhyand.com/wp-content/uploads/2020/11/cCTJPelKGLhALq3r51A9uMonxKj.jpg",
"medium": "https://wp-query.andrewrhyand.com/wp-content/uploads/2020/11/cCTJPelKGLhALq3r51A9uMonxKj-200x300.jpg",
"thumbnail": "https://wp-query.andrewrhyand.com/wp-content/uploads/2020/11/cCTJPelKGLhALq3r51A9uMonxKj-150x150.jpg"
}
},
{
"id": 551,
"title": "Enemy Lines",
"description": "In the frozen, war torn landscape of occupied Poland during World War II, a crack team of allied commandos are sent on a deadly mission behind enemy lines to extract a rocket scientist from the hands of the Nazis.",
"...and so on"
}
]
}
默认/覆盖WP_Query参数
默认参数
如果您想在请求参数应用之前添加默认的WP_Query $args,请使用此过滤器。
// Example add_filter('boxybird/query/default-args', function ($args) { $args['posts_per_page'] = 12; return $args; });
注意:上述内容仅是默认值。这意味着,如果传入的请求指定了
posts_per_page,则将覆盖boxybird/query/default-args过滤器默认值。
覆盖参数
如果您想在运行WP_Query之前修改/删除传入的请求参数,请使用此过滤器。
// Example. add_filter('boxybird/query/override-args', function ($args) { // Don't allow more than 20 'posts_per_page'. if (isset($args['posts_per_page']) && $args['posts_per_page'] > 20) { $args['posts_per_page'] = 20; } // Always override 'post_status' $args['post_status'] = 'publish'; return $args; });
注意:上述过滤器可以视为一层安全层。如果您永远不想将
$arg传递给WP_Query,请在这里操作!
权限回调
如果您想保护对/wp-json/boxybird/wp-query/v1/args端点的访问,请使用此过滤器。
// Basic Example. add_filter('boxybird/query/permission', function () { // Only logged in users have access. return is_user_logged_in(); }); // Example taken from the WordPress docs. add_filter('boxybird/query/permission', function () { // Restrict endpoint to only users who have the edit_posts capability. if (!current_user_can('edit_posts')) { return new WP_Error('rest_forbidden', esc_html__('OMG you can not view private data.', 'my-text-domain'), ['status' => 401]); } // This is a black-listing approach. You could alternatively do this via white-listing, by returning false here and changing the permissions check. return true; });
