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; });