I have a wordpress instance full of custom post types called "games". Each game can have a rating. The main query on the frontpage uses this query:
public function my_modify_main_query( $query ) {
if ( $query->is_home() && $query->is_main_query() ) { // Run only on the homepage
$query->set( 'post_type', array( 'game', 'post' ) );
$query->set( 'tax_query', array(
'relation' => 'OR',
array(
'taxonomy' => 'platform',
'field' => 'id',
'terms' => array(
3, //PS4
1312, //PC
158, //XBOX ONE
10158, //Switch
),
'operator' => 'IN'
)
) );
$meta_query = array(
array(
'key' => 'score_count',
'value' => '0',
'type' => 'numeric',
'compare' => '>',
),
);
$query->set( 'meta_query', $meta_query );
}
The result are all games which have a rating sorted by release date.
Since I always wanted to add an app for this page I started using WP-JSON. First, I tried to alter the main query of the wp-json endpoint after I added
'show_in_rest' => true
to the init of the custom post type: /wp-json/wp/v2/games
But I was unable to query for the same complex result only by using parameters.
So I started writing my own endpoint:
function shortscore_register_api_hooks() {
$namespace = 'shortscore/v1';
register_rest_route( $namespace, '/list-recent-rated-games/', array(
'methods' => 'GET',
'callback' => 'shortscore_get_recent_rated_games',
) );
}
function shortscore_get_recent_rated_games() {
if ( 0 || false === ( $result = get_transient( 'shortscore_recent_rated_games' ) ) ) {
$args = array(
'posts_per_page' => 10,
'post_type' => 'game',
'tax_query',
array(
'relation' => 'OR',
array(
'taxonomy' => 'platform',
'field' => 'id',
'terms' => array(
3, //PS4
1312, //PC
158, //XBOX ONE
10158, //Switch
),
'operator' => 'IN'
)
),
'meta_query' => array(
array(
'key' => 'score_count',
'value' => '0',
'type' => 'numeric',
'compare' => '>',
),
),
);
$query = new WP_Query( $args );
$rated_games = $query->posts;
foreach ( $rated_games as $game ) {
$result[] = array(
'ID' => $game->ID,
'title' => $game->post_title,
'cover' => get_the_post_thumbnail_url( $game->ID, array( 120, 120 ) ),
'cover_double' => get_the_post_thumbnail_url( $game->ID, array( 240, 240 ) ),
'permalink' => get_permalink( $game->ID ),
'score_count' => intval( get_post_meta( $game->ID, 'score_count', true ) ),
'score_value' => intval( get_post_meta( $game->ID, 'score_value', true ) ),
);
}
// cache for 10 minutes
set_transient( 'shortscore_recent_rated_games', $result, 60 * 10 );
}
$response = new WP_REST_Response( $result );
$response->header( 'Access-Control-Allow-Origin', apply_filters( 'shortscore_access_control_allow_origin', '*' ) );
return $response;
}
This works well but in this case I would have to add a pagination on my own.
Is this the correct way to do this? Can't I just extend the main query and get all the things like pagination for free with x-headers and everything? How would you approach the problem? Add pagination to this custom endpoint or is there a way to extend the main query of WP-JSON with standard paramters for pagination?