aucor/wp_query-route-to-rest-api

为 REST API 添加新路由 /wp-json/wp_query/args/

安装次数: 7,241

依赖: 0

建议者: 0

安全: 0

星标: 71

关注者: 11

分支: 9

开放问题: 1

类型:wordpress-plugin

1.3.2 2022-04-12 11:47 UTC

This package is not auto-updated.

Last update: 2024-09-24 23:36:27 UTC


README

贡献者: Teemu Suoranta, Sami Keijonen, Christian Nikkanen

标签: WordPress, REST API, WP_Query

许可: GPLv2+

描述

向 REST API 添加新路由 /wp-json/wp_query/args/。您可以使用 WP_Query 参数进行内容查询。有许多过滤器和方法可以限制或扩展功能。

如何使用

基本用法

路由: /wp-json/wp_query/args/

获取三个项目: /wp-json/wp_query/args/?post_type=project&posts_per_page=3

您不应该手动编写查询参数!当您想要传递例如带有 meta_query 的数组时,这会变得非常复杂。

使用 PHP

1. 创建 $args

$args = array(
  'post_type' => 'post',
  'orderby' => 'title',
  'order' => 'ASC'
);

2. 将 $args 转换为查询字符串 (参考)

$query_str = build_query( $args );

3. 进行调用

$response = wp_remote_get( 'https://your-site.local/wp-json/wp_query/args/?' . $query_str );

// Get array of "post objects"
$posts = json_decode( wp_remote_retrieve_body( $response ) );

使用 JS

1. 创建参数

var args = {
  'post_type': 'post',
  'orderby': 'title',
  'order': 'ASC'
};

2 a) 使用例如 @wordpress/url 包创建参数

import { addQueryArgs } from '@wordpress/url';

const endpointURL = addQueryArgs( '/wp-json/wp_query/args/', args );

2 b) 其他 JS 解决方案 query-string 处理大多数用例,但由于查询字符串并没有真正标准化,所以效果可能会有所不同。

一个它无法胜任的例子

const params = {
  "paged": 1,
  "order": "desc",
  "posts_per_page": 1,
  "tax_query": [
    {
      "taxonomy": "category",
      "field": "term_id",
      "terms": [
        1
      ]
    },
    {
      "taxonomy": "category",
      "field": "term_id",
      "terms": [
        2
      ]
    }
  ]
}

一个可能的解决方案,ES2015

let qsAdditions = ''

if (params.tax_query) {
  // Define a helper method for getting a querystring part
  const part = (i, key, value) => Array.isArray(value)
    ? value.reduce((acc, v, i2) => (
      acc += `&tax_query[${i}][${key}][${i2}]=${v}`
    ), '')
    : `&tax_query[${i}][${key}]=${value}`

  // Loop the params and glue pieces of querystrings together
  qsAdditions += params_tax_query.reduce((acc, cond, i) => (
    acc += part(i, 'taxonomy', cond.taxonomy || 'category') +
      part(i, 'field', cond.field || 'term_id') +
      part(i, 'terms', cond.terms)
  ), '')

  // Delete value from object so query-string won't parse it
  delete params.tax_query
}

const query_str = querystring.stringify(params) + qsAdditions

2 c) 使用 jQuery 创建参数

var query_str = jQuery.param( args );

3. 进行调用

fetch( addQueryArgs( '/wp-json/wp_query/args/', args ) )
  .then( function ( response ) {
    // The API call was succesful.
    if ( response.ok ) {
      return response.json();
    } else {
      return Promise.reject( response );
    }
  } ).then( function ( data ) {
    // Do something with data.
    console.log( data );
  } ).catch( function ( err ) {
    // There was an error.
    console.warn( 'Something went wrong.', err );
  } );

或者使用 jQuery。

$.ajax({
  url: 'https://your.site.local/wp-json/wp_query/args/?' + query_str,
}).done(function( data ) {
  console.log( data );
});

高级示例

高级示例:tax_query

获取同时具有 两个 标签 "wordpress" 和 "woocommerce" 的文章

PHP

$args = array(
  'post_type' => 'post',
  'tax_query' => array(
    array(
      'taxonomy' => 'post_tag',
      'field'    => 'slug',
      'terms'    => array( 'wordpress' ),
    ),
    array(
      'taxonomy' => 'post_tag',
      'field'    => 'slug',
      'terms'    => array( 'woocommerce' ),
    ),
  ),
);

JS

var args = {
  'post_type': 'post',
  'tax_query': [
    {
      'taxonomy': 'post_tag',
      'field': 'slug',
      'terms': [ 'wordpress' ]
    },
    {
      'taxonomy': 'post_tag',
      'field': 'slug',
      'terms': [ 'woocommerce' ]
    }
  ]
};

高级示例:带关系的 tax_query

获取具有 任一 "wordpress" 或 "woocommerce" 标签的文章。这有点棘手,因为 JS 不支持与 PHP 完全相同的数组结构。如果您只需要 PHP,这很简单。

PHP

$args = array(
  'post_type' => 'post',
  'tax_query' => array(
    'relation' => 'OR',
    array(
      'taxonomy' => 'post_tag',
      'field'    => 'slug',
      'terms'    => array( 'wordpress' ),
    ),
    array(
      'taxonomy' => 'post_tag',
      'field'    => 'slug',
      'terms'    => array( 'woocommerce' ),
    ),
  ),
);

JS

var args = {
  'post_type': 'post',
  'tax_query': {
    'relation': 'OR',
    0: {
      'taxonomy': 'post_tag',
      'field': 'slug',
      'terms': [ 'wordpress' ]
    },
    1: {
      'taxonomy': 'post_tag',
      'field': 'slug',
      'terms': [ 'woocommerce' ]
    }
  }
};

对于其他用途,请注意 JS 对象/数组语法。如果有键+值,使用对象 {}。如果没有键,只使用值,则使用数组 []

高级示例:修改现有的 WP_Query(文章存档、分类存档、搜索等)

有时您需要创建一些功能,这些功能对 WordPress、主题或插件已经定义的当前查询进行微调。这包括“加载更多”按钮、过滤器等。如果您想从头开始创建该查询,当然可以,但有一个巧妙的方法可以获取 JS 的当前查询。

您可以将此添加到您的 archive.php 或您需要的任何 PHP 模板中

<?php
// Get the main WP_Query for archive, term, single-post etc
global $wp_query;
?>
<script>var wp_query = <?php echo json_encode( $wp_query->query ) ?>;</script>

现在您可以从这个变量 wp_query 访问查询。归功于 @timiwahalahti 的这个想法。

限制

默认情况下,路由 /wp-json/wp_query/args/ 为查询设置了一些限制。这些限制可以通过过滤器和方法来解除或加强。

允许的参数

'p',
'name',
'title',
'page_id',
'pagename',
'post_parent',
'post_parent__in',
'post_parent__not_in',
'post__in',
'post__not_in',
'post_name__in',
'post_type', // With restrictions
'posts_per_page', // With restrictions
'offset',
'paged',
'page',
'ignore_sticky_posts',
'order',
'orderby',
'year',
'monthnum',
'w',
'day',
'hour',
'minute',
'second',
'm',
'date_query',
'inclusive',
'compare',
'column',
'relation',
'post_mime_type',
'author',
'author_name',
'author__in',
'author__not_in',
'meta_key',
'meta_value',
'meta_value_num',
'meta_compare',
'meta_query',
's',
'cat',
'category_name',
'category__and',
'category__in',
'category__not_in',
'tag',
'tag_id',
'tag__and',
'tag__in',
'tag__not_in',
'tag_slug__and',
'tag_slug__in',
'tax_query',
'lang', // Polylang

最大的缺失可能与获取你不需要的内容有关,例如post_status草稿(如果你需要,可以将此参数添加到过滤器的列表中)。默认情况下,不查询post_passwords或随意调整缓存设置。

文章类型

默认情况下,所有标记为'show_in_rest' => true的帖子类型都是可用的。'post_type' => 'any'将回退到这些帖子类型。你可以使用过滤器更改帖子类型到你想要的类型。

文章状态

默认情况下,只允许“发布”。根据需要,使用过滤器添加其他post_status。

限制故障安全

除了限制WP_Query参数外,还有查询后的检查,以确保查询的帖子不是被禁止的帖子类型或post_status。

默认 WP_Query

$default_args = array(
  'post_status'     => 'publish',
  'posts_per_page'  => 10,
  'has_password'    => false
);

除了WP_Query的正常默认设置外。

额外的插件兼容性功能

此插件内置了对Relevanssi ('s' 参数)Polylang ('lang' 参数)的兼容性。

过滤器

添加更多允许的参数

function my_allowed_args($args) {
  $args[] = 'post_status';
  return $args;
}
add_filter( 'wp_query_route_to_rest_api_allowed_args', 'my_allowed_args' );

添加更多默认参数

function my_default_args($args) {
  $args['posts_per_page'] = 5;
  return $args;
}
add_filter( 'wp_query_route_to_rest_api_default_args', 'my_default_args' );

添加允许的帖子类型

你还可以通过在注册帖子类型时设置'show_in_rest' => true来添加帖子类型。

function my_allowed_post_types($post_types) {
  $post_types[] = 'projects';
  return $post_types;
}
add_filter( 'wp_query_route_to_rest_api_allowed_post_types', 'my_allowed_post_types' );

添加允许的帖子状态

function my_allowed_post_status($post_status) {
  $post_status[] = 'draft';
  return $post_status;
}
add_filter( 'wp_query_route_to_rest_api_allowed_post_status', 'my_allowed_post_status' );

当前帖子是否允许

function my_post_is_allowed($is_allowed, $post) {
  if($post->ID == 123) {
    $is_allowed = false;
  }
  return $is_allowed;
}
add_filter( 'wp_query_route_to_rest_api_post_is_allowed', 'my_post_is_allowed', 10, 2 );

修改任何参数值

function my_arg_value($value, $key, $args) {
  if($key == 'posts_per_page' && $value > 10) {
    $value = 10;
  }
  return $value;
}
add_filter( 'wp_query_route_to_rest_api_arg_value', 'my_arg_value', 10, 3 );

检查权限

function my_permission_check($is_allowed, $request) {
  return true;
}
add_filter( 'wp_query_route_to_rest_api_permissions_check', 'my_permission_check', 10, 2 );

限制每页最大帖子数

function my_max_posts_per_page($max) {
  return 100; // Default 50
}
add_filter( 'wp_query_route_to_rest_api_max_posts_per_page', 'my_max_posts_per_page' );

修改默认 $data

function my_default_data($data) {
  $data = array(
    'html'     => false,
    'messages' => array(
      'empty' => esc_html__( 'No results found.', 'text-domain' ),
    ),
  );

  return $data;
}
add_filter( 'wp_query_route_to_rest_api_default_data', 'my_default_data' );

循环后修改 $data

function my_default_data($data, $wp_query, $args) {
  // Do something with the data.

  return $data;
}
add_filter( 'wp_query_route_to_rest_api_after_loop_data', 'my_default_data', 10, 3 );

删除帖子类型元数据

add_filter( 'wp_query_route_to_rest_api_update_post_type_meta', '__return_false' );

删除父类

add_filter( 'wp_query_route_to_rest_api_use_parent_class', '__return_false' );

钩子

在WP_Query之前

function my_before_query($args) {
  // do whatever
}
add_action( 'wp_query_route_to_rest_api_before_query', 'my_before_query' );

在WP_Query之后

function my_after_query($wp_query) {
  // do whatever
}
add_action( 'wp_query_route_to_rest_api_after_query', 'my_after_query' );

安装

下载并激活。就是这样。

Composer

$ composer require aucor/wp_query-route-to-rest-api

使用composer.json

{
  "require": {
    "aucor/wp_query-route-to-rest-api": "*"
  },
  "extra": {
    "installer-paths": {
      "htdocs/wp-content/plugins/{$name}/": ["type:wordpress-plugin"]
    }
  }
}

问题和功能愿望单

这是一个第三方开发者开发的WordPress插件。WordPress.org或Automattic与此插件无关。没有任何保修或保证。请谨慎处理。

如果你看到有缺失的关键功能,请贡献!

在寻找与WP_User_Query类似的API吗?

安装MEOM/meom-user-query

变更日志

1.3.2

修复由1.3.0参数重构引起的PHP警告。

1.3.1

修复composer许可证为有效许可证。

1.3.0

兼容性发布,新增了一些新功能。100%向后兼容。

  • 现在允许自定义HTML输出(#10)
  • 实例和参数净化现在可以重用(#11)
  • 修复了过滤器名称中的错误,同时保持旧名称也有效(#5)
  • 更新WP版本、插件版本和某些readme调整

1.2.0

WordPress.org发布。

1.1.1

在readme中添加了获取PHP WP_Query的详细示例。添加了目录。使标题层次更合理。

1.1

使返回的数据结构相同于/wp-json/wp/posts/。之前数据模式缺少一些数据。现在结构继承自WP_REST_Posts_Controller,正如它应该从一开始就是这样。