Отримайте меню навігації WP від ​​API REST API V2


14

Я намагаюся отримати меню навігації з відповіді JSON, використовуючи плагін WP REST API v2 .

Немає розширення плагіну меню навігації для REST API v2 , а лише для V1.

З коду WordPress Types Types я дізнався, що меню навігації трактується як тип публікації.

Від Rest API Doc ось так ми отримуємо повідомлення типу:

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

Я намагався це зробити так:

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

Я отримав помилку 403.

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

сервер зрозумів мій запит, але він відмовився надати дані.

З: Як я можу це виправити?


Усі ці відповіді просто жахливі. Встановіть це, продовжте це. Це вже має бути вбудованим, громада повинна відкрити випуск на GitHub.
SacWebDeveloper

Відповіді:



48

Оскільки мені це не подобається, коли головна відповідь - «Встановити плагін X», ось як я це вирішив:

Наразі меню не доступне у WP Rest. Тож, що вам потрібно зробити, це зареєструвати власну власну кінцеву точку, а потім просто зателефонувати по тому маршруту зі своєї програми, яка цього потребує.

Отже, ви б включили щось подібне (до своїх функцій.php, плагіна, де б не було):

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

У наведеному вище прикладі ви отримаєте доступ до даних із:

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

Ви можете використовувати вищевказаний метод для створення будь-яких маршрутів, які вам подобаються, для отримання будь-якого типу даних, недоступних у WP Rest. Також добре, якщо вам потрібно обробити деякі дані, перш ніж надсилати їх у вашу заявку.


4
дякую за те, що ви поділилися своїм вирішенням із більш ніж просто посиланням на плагін ;-) Хоча було б краще встановити імена своїх функцій або використовувати простір імен, щоб уникнути можливого зіткнення імен, як get_menu()це досить загально.
birgire

Дивовижно, люди не розуміють, що більшість людей вже мають від 30 до 70 плагінів. Вони навіть мають плагіни, щоб не відключати інших! це божевільно. Я думаю, що я збираюся встановити плагін, щоб зберегти цю нитку.
Ігнасіо Бустос

це робить лише вихідfalse
moesphemie

1

@Liren відповідь працює добре. Однак мало хто з початківців може не мати можливості коригувати маршрут. Ось код, який добре працює з WordPress Rest API v2 з мінімальною модифікацією.

Замініть ім'я меню лише у функції wp_get_nav_menu_items () . Якщо ім'я та куля меню не працюють (Повернути помилково), використовуйте ідентифікатор меню (видно на інформаційній панелі під час редагування цього меню).

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

URL-адреса маршруту:

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

Більш детально описано в Підручнику: API WordPress Rest - Отримайте елементи навігаційного меню


Це гарне рішення для лише одного маршруту
juanitourquiza


0

Я не думаю, що плагін слід використовувати для подібних завдань. Також відповідь hkc насправді не така вже й погана, для цього потрібне лише додаткове пояснення, щоб зробити цю роботу з nav_menu_itemтипом публікації (тієї, що використовується для меню навігації по WP).

Цей тип публікації вже зареєстрований, і тому нам потрібно його змінити, це легко зробити, підключившись до register_post_type_argsфільтра. Цей фільтр дозволяє нам змінювати аргументи для конкретного типу публікації. Код нижче показує саме те, що стосується 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);

Як ви могли помітити з наведеного вище коду, цей код трохи більше, ніж просто показ типу публікації в REST. Він також змінює контролер REST за замовчуванням, щоб показати дещо подібний вихід у REST, як описано у відповіді Лірена . Хоча поряд з цим, він також робить все те, що роблять всі контролери REST посту, і, таким чином, дає вам більше контролю та функціональності. Також розглядайте це як більш стабільний варіант, оскільки він не буде конфліктувати з іншими маршрутами REST, і останнє, але не менш важливо, це також зручніше працювати.


0

Я погоджуюся з відповіддю @Lirens, але меню слід називати ідентифікатором, а не слизом. Також нахил перед контуром меню не потрібен. Тож стає щось подібне:

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

Так, це працювало для мене.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.