WP-API 在特定日期后获取帖子

WP-API Get Posts After a Specific Date

我将 Version 2.0-beta15 与继承自 WP_REST_Posts_Controller 的自定义 post 类型一起使用,但需要根据 acf 字段查询日期。哎呀!

端点参数

/wp-json/wp/v2/almanac_entry?per_page=3&filter[orderby]=acf_almanac_date&after=2016-12-23T00:00:00&filter[date_query[column]]=acf_almanac_date

回应

回复returns 三项但应该只有两项,其中两项在列出的日期之后,第三个在列出的日期之前。以下是 acf_almanac_date 字段的三个项目值:

  1. 2016-12-31T00:00:00
  2. 2016-12-24T00:00:00
  3. 2016-12-17T00:00:00(这个日期早于2016-12-23T00:00:00,应该已经返回)

代码

操作注册为:

add_action( 'init', 'register_custom_post_types' );
function register_custom_post_types() {
    global $wp_post_types;

    $post_type_name = 'almanac_entry';
    if( isset( $wp_post_types[ $post_type_name ] ) ) {
        $wp_post_types[$post_type_name]->show_in_rest = true;
        $wp_post_types[$post_type_name]->rest_base = $post_type_name;
        $wp_post_types[$post_type_name]->rest_controller_class = 'WP_REST_Posts_Controller';
    }
}

add_action( 'rest_api_init', 'wp_rest_add_custom_fields' );
function wp_rest_add_custom_fields() {
    register_rest_field('almanac_entry', 'acf_almanac_date', array (
    'get_callback' => function($object, $field_name, $request) {
      return get_post_meta( $object[ 'id' ], 'almanac_date', true ) . "T00:00:00";
    },
    'update_callback' => null,
    'schema'          => null,
  ));
}

非常感谢任何帮助。


启示录 1

我突然想到,也许参数 filter[date_query[column]]=acf_almanac_date 有 WP-API 查询在 wp_rest_add_custom_fields 函数中动态添加的字段 acf_almanac_date

也许我需要扩展 WP_REST_Posts_Controller 并覆盖 prepare_items_query 函数?如果为真,我如何将其与 ACF 字段相关联 acf_almanac_date?哎呀呀!

WordPress REST API 不允许通过开箱即用的 post 元值进行查询,因为它认为它们是私有的。要通过 post 元值启用查询,您需要:

  1. 将查询参数注册到 Post 控制器。
  2. 将请求参数转换为传递给 WP_Query 的查询参数。

这里有一些适用于 WordPress 4.7 的代码:

// Set the post type to modify.
$post_type = 'almanac_entry';

/**
 * Register `almanac_date_before` and `almanac_date_after`
 * as collection query params.
 *
 * Also support ordering by the `almanac_date` meta value.
 */
add_filter( "rest_{$post_type}_collection_params", function( $params ){
    $params['almanac_date_before'] = array(
        'description'        => __( 'Limit response to posts published before a given ISO8601 compliant date.' ),
        'type'               => 'string',
        'format'             => 'date-time',
    );
    $params['almanac_date_after'] = array(
        'description'        => __( 'Limit response to posts published after a given ISO8601 compliant date.' ),
        'type'               => 'string',
        'format'             => 'date-time',
    );
    $params['orderby']['enum'][] = 'almanac_date';
    return $params;
});

/**
 * Transform almanac_date_before` and `almanac_date_after` into a meta query.
 */
add_filter( "rest_{$post_type}_query", function( $query_args, $request ){
    if ( isset( $request['almanac_date_before'] ) ) {
        if ( ! is_array( $query_args['meta_query'] ) ) {
            $query_args['meta_query'] = array();
        }
        // We only want the 2016-11-23 from 2016-11-23T00:00:00
        $bits = explode( 'T', $request['almanac_date_before'] );
        $query_args['meta_query'][] = array(
            'key'      => 'almanac_date',
            'value'    => $bits[0],
            'compare'  => '<=',
            'type'     => 'DATE',
        );
    }
    if ( isset( $request['almanac_date_after'] ) ) {
        if ( ! is_array( $query_args['meta_query'] ) ) {
            $query_args['meta_query'] = array();
        }
        // We only want the 2016-11-23 from 2016-11-23T00:00:00
        $bits = explode( 'T', $request['almanac_date_after'] );
        $query_args['meta_query'][] = array(
            'key'      => 'almanac_date',
            'value'    => $bits[0],
            'compare'  => '>=',
            'type'     => 'DATE',
        );
    }
    return $query_args;
}, 10, 2 );