it-swarm.com.de

Erhalten WP Navigationsmenü von REST API V2

Ich versuche, das Navigationsmenü über das WP REST API v2 plugin aus der JSON-Antwort abzurufen.

Für die REST API v2 gibt es keine Erweiterung für das Navigationsmenü-Plugin, sondern nur für V1.

Aus Codex WordPress-Beitragstypen habe ich erfahren, dass das Navigationsmenü als Beitragstyp behandelt wird.

Aus Rest API Doc erhalten wir Posts eines Typs:

GET http://demo.wp-api.org/wp-json/wp/v2/types/<type>

Ich habe versucht, es so zu verstehen:

URL : http://localhost/wptest/wp-json/wp/v2/types/nav_menu_item

Ich habe den Fehler 403 erhalten.

{"code":"rest_cannot_read_type","message":"Cannot view type.","data":{"status":403}}

der Server hat meine Anfrage verstanden, aber es wurde abgelehnt, die Daten weiterzugeben.

F: Wie kann ich das beheben?

12
Murhaf Sousli

Es gibt eine Plugin-Erweiterung für das Navigationsmenü für die REST API v2: https://wordpress.org/plugins/wp-api-menus/

6
Yan Takushevich

Da es mir selbst nicht gefällt, wenn die Antwort "Install plugin X" lautet, habe ich es folgendermaßen gelöst:

Menüs sind derzeit in der WP -Rest nicht verfügbar. Sie müssen also Ihren eigenen benutzerdefinierten Endpunkt registrieren und dann nur die Route aus Ihrer Anwendung aufrufen, die sie benötigt.

Also würden Sie so etwas einbinden (in Ihrer functions.php, plugin, wo auch immer):

function get_menu() {
    # Change 'menu' to your own navigation slug.
    return wp_get_nav_menu_items('menu');
}

add_action( 'rest_api_init', function () {
        register_rest_route( 'myroutes', '/menu', array(
        'methods' => 'GET',
        'callback' => 'get_menu',
    ) );
} );

Für das obige Beispiel würden Sie auf die Daten zugreifen von:

http://your-domain.dev/wp-json/myroutes/menu

Mit der oben beschriebenen Methode können Sie beliebige Routen erstellen, um alle Datentypen abzurufen, die im WP Rest nicht verfügbar sind. Auch gut, wenn Sie einige Daten verarbeiten müssen, bevor Sie sie an Ihre Bewerbung senden.

34
Liren

Ich denke nicht, dass ein Plugin für diese Art von Aufgaben verwendet werden sollte. Auch hkcs Antwort ist eigentlich nicht so schlimm, es bedarf nur einer weiteren Erklärung, damit dies mit dem Post-Typ nav_menu_item funktioniert (der für wp-Navigationsmenüs verwendet wird).

Dieser Beitragstyp ist bereits registriert und daher müssen wir ihn ändern. Dies erfolgt einfach durch Einbinden in den register_post_type_args-Filter. Mit diesem Filter können wir die Argumente für einen bestimmten Beitragstyp ändern. Der folgende Code zeigt genau das für den Beitragstyp nav_menu_item.

add_filter('register_post_type_args', function ($args, $post_type) {
    if ($post_type == 'nav_menu_item' &&
        class_exists('WP_REST_Posts_Controller') &&
        !class_exists('WP_REST_NavMenuItem_Controller')) {

        class WP_REST_NavMenuItem_Controller extends WP_REST_Posts_Controller {
            public function get_items( $request ) {
                $args = wp_parse_args($request, [
                    'order' => 'ASC',
                    'orderby' => 'menu_order',
                ]);

                $output = [];

                if (empty($request['menu'])) {
                    $menus = get_registered_nav_menus();

                    foreach ( $menus as $location => $description ) {
                        $items = wp_get_nav_menu_items($location, $args);
                        $output = array_merge($output, is_array($items) ? $items : []);
                    }
                } else {
                    $items = wp_get_nav_menu_items($request['menu'], $args);
                    $output = array_merge($output, is_array($items) ? $items : []);
                }

                return rest_ensure_response($output);
            }

            public function get_collection_params() {
                $query_params = parent::get_collection_params();
                $query_params['menu'] = [
                    'description' => __( 'The name or also known as theme_location of the menu' ),
                    'type' => 'string',
                ];
                return $query_params;
            }
        }

        // Alter the post type arguments
        $args['show_in_rest'] = true;
        $args['rest_controller_class'] = 'WP_REST_NavMenuItem_Controller';
    }
    return $args;
}, 10, 2);

Wie Sie vielleicht anhand des obigen Codes bemerkt haben, zeigt der Code nicht nur den Beitragstyp im REST an. Außerdem wird der Standard-Posts-Controller REST so geändert, dass in REST eine ähnliche Ausgabe angezeigt wird, wie in Lirens Antwort beschrieben. Daneben werden jedoch auch die Funktionen aller Post-Type-Controller REST ausgeführt, wodurch Sie mehr Kontrolle und Funktionalität erhalten. Betrachten Sie dies auch als stabilere Option, da sie nicht mit anderen REST - Routen in Konflikt gerät und nicht zuletzt auch komfortabler zu handhaben ist.

0
Fleuv

Ich stimme der Antwort von @Lirens zu, aber die Menüs sollten nach ID und nicht nach Slug aufgerufen werden. Auch der Schrägstrich vor dem Menüpfad wird nicht benötigt. So wird es ungefähr so:

function get_menu() {
    # Change '2' to your own navigation ID.
    return wp_get_nav_menu_items(2);
}

add_action( 'rest_api_init', function () {
    register_rest_route( 'myroutes', 'menu', array(
        'methods' => 'GET',
        'callback' => 'get_menu',
    ) );
} );

So hat es bei mir funktioniert.

0
Sjoerd Oudman

Sie müssen 'show_in_rest' => true, hinzufügen, während Sie den Beitragstyp registrieren.

Details finden Sie hier http://v2.wp-api.org/extending/custom-content-types/

0
hkc