boxybird/boxybird-wp-query-endpoint

使用单个REST API端点从WordPress数据库查询任何您想要的内容。

v0.1.0 2020-12-01 15:53 UTC

This package is auto-updated.

Last update: 2024-09-28 10:56:35 UTC


README

使用单个REST API端点从WordPress数据库查询任何您想要的内容。

简单来说,这个插件允许将url中的GET参数传递给WP_Query类作为$args

WP_Query参考:https://developer.wordpress.org/reference/classes/wp_query/

wp_query in javascript

安装

克隆或下载插件,并在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&hellip;",
        "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&hellip;"
      },
      "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端点的访问,请使用此过滤器。

参考:https://developer.wordpress.org/rest-api/extending-the-rest-api/routes-and-endpoints/#permissions-callback

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