Laden Sie das WP-Navigationsmenü von der REST-API V2 herunter

14

Ich versuche, das Navigationsmenü mithilfe des WP REST API v2- Plugins aus der JSON-Antwort abzurufen.

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

Durch den Codex WordPress Post Types habe ich erfahren, dass das Navigationsmenü als Beitragstyp behandelt wird.

In Rest API Doc erhalten wir auf diese Weise Beiträge 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?

Murhaf Sousli
quelle
Alle diese Antworten sind einfach schrecklich. Installiere das, erweitere das. Es sollte bereits eingebaut sein, die Community sollte ein Problem auf GitHub eröffnen.
SacWebDeveloper

Antworten:

47

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

Menüs sind derzeit in 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 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 in WP Rest nicht verfügbar sind. Auch gut, wenn Sie einige Daten verarbeiten müssen, bevor Sie sie an Ihre Anwendung senden.

Liren
quelle
4
danke, dass du deine Problemumgehung mit mehr als nur einem Plugin-Link geteilt hast ;-) Es wäre besser, deinen Funktionsnamen ein Präfix zu geben oder einen Namespace zu verwenden, um mögliche Namenskollisionen zu vermeiden, da dies get_menu()ziemlich allgemein ist.
Birgire
Genial, die Leute merken nicht, dass die meisten Leute bereits 30 bis 70 Plugins installiert haben. Sie haben sogar Plugins, um andere zu deaktivieren! es ist verrückt. Ich denke, ich werde ein Plugin installieren, um diesen Thread beizubehalten.
Ignacio Bustos
es wird nur ausgegebenfalse
Moesphemie
1

@Liren Antwort funktioniert gut. Allerdings können nur wenige Anfänger die Route möglicherweise nicht anpassen. Hier ist der Code, der mit WordPress Rest API v2 mit minimalen Änderungen gut funktioniert .

Ersetzen Sie Ihren Menünamen nur in der Funktion wp_get_nav_menu_items () . Wenn der Menüname und der Slug nicht funktionieren (Return false), verwenden Sie die Menü-ID (im Dashboard sichtbar, während Sie dieses Menü bearbeiten).

function get_my_menu() {
    // Replace your menu name, slug or ID carefully
    return wp_get_nav_menu_items('Main Navigation');
}

add_action( 'rest_api_init', function () {
    register_rest_route( 'wp/v2', 'menu', array(
        'methods' => 'GET',
        'callback' => 'get_my_menu',
    ) );
} );

Routen-URL:

https://website.com/wp-json/wp/v2/menu

Weitere Details finden Sie im Tutorial: WordPress Rest API - Navigationsmenüelemente abrufen

Deepak Rajpal
quelle
Es ist eine gute Lösung für nur eine Route
Juanitourquiza
0

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

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

hkc
quelle
register_post_type('nav_menu_item', array('show_in_rest' => true));
Fleuv
0

Ich denke nicht, dass ein Plugin für diese Art von Aufgaben verwendet werden sollte. Auch die Antwort von hkc ist eigentlich nicht so schlecht, es bedarf nur einiger weiterer Erklärungen, damit dies mit dem nav_menu_itemBeitragstyp (der für WP-Navigationsmenüs verwendet wird) funktioniert .

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

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-REST-Controller "Posts" so geändert, dass im REST eine ähnliche Ausgabe angezeigt wird, wie in der Antwort von Liren beschrieben . Daneben werden jedoch auch die Funktionen aller REST-Post-Controller 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 bearbeiten ist.

Fleuv
quelle
0

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.

Sjoerd Oudman
quelle