Pobierz menu nawigacyjne WP z REST API V2


14

Próbuję uzyskać menu nawigacyjne z odpowiedzi JSON przy użyciu wtyczki WP REST API v2 .

Nie ma rozszerzenia wtyczki menu nawigacyjnego dla REST API v2 , ale tylko dla V1.

Z kodów pocztowych WordPress Typy postów dowiedziałem się, że menu nawigacyjne jest traktowane jako typ postu.

Z dokumentu Rest API Doc oto, w jaki sposób otrzymujemy posty typu:

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

Próbowałem to zrobić tak:

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

Otrzymałem błąd 403.

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

serwer zrozumiał moją prośbę, ale odmówił podania danych.

P: Jak mogę to naprawić?


Wszystkie te odpowiedzi są po prostu okropne. Zainstaluj to, przedłuż to. Powinien być już wbudowany, społeczność powinna otworzyć problem na GitHub.
SacWebDeveloper,

Odpowiedzi:



48

Ponieważ sam nie podoba mi się, gdy najważniejszą odpowiedzią jest „Zainstaluj wtyczkę X”, oto jak to rozwiązałem:

Menu nie są obecnie dostępne w WP Rest. Musisz więc zarejestrować własny punkt końcowy, a następnie po prostu wywołać tę trasę z aplikacji, która tego potrzebuje.

Więc umieściłbyś coś takiego (w twoich functions.php, wtyczce, gdziekolwiek):

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

W powyższym przykładzie uzyskasz dostęp do danych z:

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

Możesz użyć powyższej metody, aby utworzyć dowolne trasy, aby uzyskać dowolny rodzaj danych, które nie są dostępne w WP Rest. Również dobrze, jeśli musisz przetworzyć niektóre dane przed wysłaniem ich do aplikacji.


4
dzięki za udostępnienie obejścia z czymś więcej niż tylko linkiem do wtyczki ;-) Lepiej byłoby poprzedzić nazwy funkcji lub użyć przestrzeni nazw, aby uniknąć możliwej kolizji nazw, co get_menu()jest dość ogólne.
birgire,

Niesamowite, ludzie nie zdają sobie sprawy, że większość osób ma już zainstalowanych od 30 do 70 wtyczek. Mają nawet wtyczki, które utrzymują dezaktywację innych! to jest szalone. Myślę, że zamierzam zainstalować wtyczkę, aby zachować ten wątek.
Ignacio Bustos

false
generuje

1

Odpowiedź @Liren działa dobrze. Jednak niewielu początkujących może nie być w stanie dostosować trasy. Oto kod, który działa dobrze z WordPress Rest API v2 przy minimalnej modyfikacji.

Zamień nazwę swojego menu tylko w funkcji wp_get_nav_menu_items () . Jeśli nazwa menu i informacje o pracy nie działają (Zwróć fałsz), użyj identyfikatora menu (widoczny na pulpicie nawigacyjnym podczas edycji tego menu).

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

Trasa URL:

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

Więcej szczegółów w samouczku: WordPress Rest API - Uzyskaj elementy menu nawigacyjnego


To dobre rozwiązanie, jeśli masz tylko jedną trasę
juanitourquiza


0

Nie sądzę, że do takich zadań powinna być używana wtyczka. Również odpowiedź hkc nie jest wcale taka zła, potrzebuje tylko dodatkowych wyjaśnień, aby działała z nav_menu_itemtypem postu (tym używanym do menu nawigacji wp).

Ten typ postu jest już zarejestrowany i dlatego musimy go zmienić, łatwo to zrobić, podpinając register_post_type_argsfiltr. Ten filtr pozwala nam zmieniać argumenty dla określonego typu postu. Poniższy kod pokazuje tylko ten nav_menu_itemtyp postu.

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

Jak można zauważyć z powyższego kodu, kod robi coś więcej niż tylko pokazywanie typu postu w REST. Zmienia również domyślny kontroler REST Postów, aby wyświetlać nieco podobne dane wyjściowe w REST, jak opisano w odpowiedzi Liren . Chociaż oprócz tego robi to, co robią wszystkie kontrolery REST typu post, a tym samym zapewnia większą kontrolę i funkcjonalność. Weź to również pod uwagę jako bardziej stabilną opcję, ponieważ nie kolidowałoby to z innymi trasami REST, a na koniec jest również wygodniejsze w pracy.


0

Zgadzam się z odpowiedzią @Lirens, ale menu powinny być wywoływane przez ID, a nie ślimak. Ponadto ukośnik przed ścieżką menu nie jest potrzebny. Staje się więc mniej więcej taki:

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

Tak to zadziałało dla mnie.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.