it-swarm.com.de

Ändern der WP-JSON-Hauptabfrage oder der Best Practices für benutzerdefinierte Endpunkte

Ich habe eine WordPress-Instanz mit benutzerdefinierten Beitragstypen namens "Spiele". Jedes Spiel kann eine Bewertung haben. Die Hauptabfrage auf der Startseite verwendet diese Abfrage:

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

Das Ergebnis sind alle Spiele, deren Bewertung nach Erscheinungsdatum sortiert ist.

Da ich immer eine App für diese Seite hinzufügen wollte, begann ich mit WP-JSON. Zuerst habe ich versucht, die Hauptabfrage des wp-json-Endpunkts zu ändern, nachdem ich hinzugefügt habe

'show_in_rest' => true

zum Init des benutzerdefinierten Post-Typs:/wp-json/wp/v2/games

Es war mir jedoch nicht möglich, dasselbe komplexe Ergebnis nur mithilfe von Parametern abzufragen.

Also habe ich angefangen, meinen eigenen Endpunkt zu schreiben:

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

Das funktioniert gut aber in diesem Fall müsste ich selbst eine Paginierung hinzufügen.

Ist dies der richtige Weg, um dies zu tun? Kann ich nicht einfach die Hauptabfrage erweitern und alle Dinge wie Paginierung kostenlos mit X-Headern und allem bekommen? Wie würden Sie das Problem angehen? Fügen Sie diesem benutzerdefinierten Endpunkt eine Paginierung hinzu, oder gibt es eine Möglichkeit, die Hauptabfrage von WP-JSON mit Standardparametern für die Paginierung zu erweitern?

1
Marc

Sie machen das Richtige. Theoretisch können Sie wahrscheinlich die "normale" API-Anforderung abfangen und den relevanten wp_query nach Bedarf ändern. Dies bedeutet jedoch, dass Sie diese API ändern und überschreiben und sie irgendwann in ihrer "jungfräulichen" Form benötigen wird nicht verfügbar sein.

Was die Paginierung betrifft, müssen Sie zwar Ihre eigenen erstellen, aber es ist tatsächlich viel einfacher, dies als im HTML-Front-End zu tun. Sie müssen lediglich die Seitennummer in Ihrer JS-Verarbeitungsroutine behalten und die angeforderte Seite senden als Teil der Anfrage.

1
Mark Kaplun