web-dev-qa-db-fra.com

Comment modifier la requête principale WP-JSON ou les meilleures pratiques pour les points de terminaison personnalisés

J'ai une instance wordpress pleine de types d'articles personnalisés appelés "jeux". Chaque jeu peut avoir une note. La requête principale sur la page d'accueil utilise cette requête:

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

Le résultat est tous les jeux qui ont une note triée par date de sortie.

Depuis que j'ai toujours voulu ajouter une application pour cette page, j'ai commencé à utiliser WP-JSON. J'ai d'abord essayé de modifier la requête principale du noeud final wp-json après avoir ajouté

'show_in_rest' => true

à l'init du type de message personnalisé:/wp-json/wp/v2/games

Mais je n'ai pas pu interroger le même résultat complexe uniquement à l'aide de paramètres.

J'ai donc commencé à écrire mon propre terminal:

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

Cela fonctionne bien mais dans ce cas, je devrais ajouter une pagination par moi-même.

Est-ce la bonne façon de faire cela? Est-ce que je ne peux pas simplement étendre la requête principale et obtenir toutes les choses comme la pagination gratuitement avec les en-têtes x et tout? Comment aborderiez-vous le problème? Ajoutez une pagination à ce noeud final personnalisé ou existe-t-il un moyen d'étendre la requête principale de WP-JSON avec des paramètres standard pour la pagination?

1
Marc

Vous faites la bonne chose. En théorie, vous pouvez probablement intercepter la requête "normale" de l'API et modifier le wp_query approprié en fonction de vos besoins, mais cela signifie que vous modifiez et substituez cette API et si vous en avez besoin dans sa forme "vierge" à un moment donné, ne sera pas disponible.

En ce qui concerne la pagination, il est vrai que vous devez créer le vôtre, mais il est en réalité beaucoup plus facile de le faire que sur le frontal HTML. Tout ce dont vous avez besoin est de conserver le numéro de page dans votre routine de traitement JS et d'envoyer la page demandée. dans le cadre de la demande.

1
Mark Kaplun