何时使用WordPress REST API检查max_num_ages?

时间:2019-03-22 作者:grazianodev

我正在使用WP API实现无限加载,所以我通过API请求引入新帖子。因为默认API响应对我来说很好,而且我只需要过滤返回的帖子,所以我没有创建自定义路由,而是自定义默认查询:

add_filter( \'rest_post_query\', array( $this, \'get_posts\' ), 10, 2 );

public function get_posts( $args, $req ) {    

    /*
    This function is used to retrieve posts of the \'post\' and \'news\' type
    */

    $cat = $req[ \'category\' ];
    $page = $req[ \'page\' ];  
    $tag = $req[ \'tag\' ];
    $type = $req[ \'type\' ]; 

    $args[ \'paged\' ] = isset( $page ) ? $page : 1;
    $args[ \'posts_per_page\' ] = 8;  
    $args[ \'category_name\' ] = isset( $cat ) && ! empty( $cat ) ? $cat : null;
    $args[ \'tag\' ] = isset( $tag ) && ! empty( $tag ) ? $tag : null;
    $args[ \'post_type\' ] = 
        isset( $type ) && ! empty( $type ) ? array( $type ) : array( \'post\', \'news\' ); 

    return $args;

}
不过,我对分页有问题。假设我有10页的结果,我请求第20页:API的默认行为是抛出以下错误:

{
    "code": "rest_post_invalid_page_number",
    "message": "The page number requested is larger than the number of pages available.",
    "data": {
        "status": 400
    }
}
我想做的是返回一个空数组,因为在前端处理会更容易、更直观。所以我想我应该检查一下max_num_pages属性,但我不知道在哪里执行该操作。

我试过这样做:

add_action( \'pre_get_posts\', array( $this, \'check_pagination_limit\' ) ); 

public function check_pagination_limit( $query ) {
    if( ! is_admin() ) {
        $currentPage = $query->get(\'paged\'); 
        $lastPage = $query->max_num_pages; 
        if( $currentPage > $lastPage ) {
            $query->set(\'post__in\', array(0)); 
        }
    }
}
但是pre_get_postsrest_post_query 正在使用。。。有没有rest_ 在发送响应之前可以用来访问查询的过滤器或挂钩?

2 个回复
最合适的回答,由SO网友:tmdesigned 整理而成

pre_get_posts 对REST请求进行激发。

复制函数并单步执行之后,代码实际上开始工作了——这是第一次。但是,WP REST控制器具有以下位:

        if ( $total_posts < 1 ) {
            // Out-of-bounds, run the query again without LIMIT for total count.
            unset( $query_args[\'paged\'] );

            $count_query = new WP_Query();
            $count_query->query( $query_args );
            $total_posts = $count_query->found_posts;
        }
这将重新运行查询,而查询又会重新运行您的函数。然而,正如您所看到的,它故意取消了“paged”参数的设置,所以这次当您比较$currentPage > $lastPage 您正在比较0 > 0 这是错误的,所以你的post__in 未设置参数,将返回帖子。你知道故事的其余部分——WordPress发现你不能拥有该页面,因为没有足够的帖子。

您可以更直接地获取该参数,因为它是get请求的一部分,例如:

    if( ! is_admin()
        && isset($_GET[\'page\']) ) {
        $currentPage = $_GET[\'page\'];
        $lastPage = $query->max_num_pages;
        if( $currentPage > $lastPage ) {
            $query->set(\'post__in\', array(0));
        }
    }
这似乎有效,但我没有彻底测试它。

老实说,你真的是在逆流而上,我认为更好的解决方案可能是从WordPress那里得到一个提示,然后针对错误响应进行内置处理。它被很好地打包为JSON,无论如何,您可能还需要注意其他错误。

此外,我认为您的函数应该检查并确保它只在REST请求时启动。现在,正如它所写的那样,它也会向其他人开火。

SO网友:birgire

请注意,naitve端点的rest响应标头包含有关找到的项目数和总页数的信息:

X-WP-Total: 10
X-WP-TotalPages: 1
这将通过javascript提供,并有助于前端分页。

用例如。

curl -I https://example.org/wp-json/wp/v2/posts
从命令行。

相关推荐

get_post_meta pagination

我有自定义字段,具有多个值的数组$metas = get_post_meta($post->ID, \"$meta_key\", false); foreach ( $metas as $metas ){ echo $metas; } 当然,这将返回一个数组。如何对此分页?例如:www.example.com/post-title/1 将返回meta_value[0]和www.example.com/post-title/2 将