Obtenga el menú de navegación de WP de REST API V2

14

Estoy tratando de obtener el menú de navegación de la respuesta JSON usando el complemento WP REST API v2 .

No hay una extensión de complemento de menú de navegación para REST API v2 , sino solo para V1.

De los tipos de publicaciones de WordPress del codex , aprendí que el menú de navegación se trata como un tipo de publicación.

Desde Rest API Doc , así es como obtenemos publicaciones de un tipo:

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

Traté de hacerlo así:

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

Recibí el error 403.

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

el servidor entendió mi solicitud pero se negó a dar los datos.

P: ¿Cómo puedo solucionar esto?

Murhaf Sousli
fuente
Todas estas respuestas son simplemente terribles. Instala esto, extiende eso. Ya debería estar integrado, la comunidad debería abrir un problema en GitHub.
SacWebDeveloper

Respuestas:

47

Como no me gusta cuando la respuesta principal es "Instalar el complemento X", así es como lo resolví:

Los menús no están disponibles actualmente en WP Rest. Entonces, lo que debe hacer es registrar su propio punto final personalizado y luego simplemente llamar a esa ruta desde la aplicación que lo necesita.

Así que incluirías algo como esto (en tu functions.php, plugin, donde sea):

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

Para el ejemplo anterior, accedería a los datos desde:

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

Puede usar el método anterior para crear cualquier ruta que desee para obtener cualquier tipo de datos que no esté disponible en el WP Rest. También es bueno si necesita procesar algunos datos antes de enviarlos a su aplicación.

Liren
fuente
44
gracias por compartir su solución alternativa, con algo más que un enlace de complemento ;-) Sin embargo, sería mejor prefijar los nombres de sus funciones o usar el espacio de nombres, para evitar una posible colisión de nombres, como get_menu()es bastante general.
birgire
Impresionante, la gente no se da cuenta de que la mayoría de las personas ya tienen instalados entre 30 y 70 complementos. ¡Incluso tienen complementos para mantener desactivados a otros! es una locura Creo que voy a instalar un complemento para mantener este hilo.
Ignacio Bustos
solo da salidafalse
moesphemie
1

La respuesta de @Liren funciona bien. Sin embargo, pocos principiantes pueden no ser capaces de ajustar la ruta. Aquí está el código que funciona bien con WordPress Rest API v2 con una modificación mínima.

Reemplace su nombre de menú solo en la función wp_get_nav_menu_items () . Si el nombre del menú y el slug no funcionan (Devolver falso), use la ID del menú (visible en el Tablero mientras edita ese Menú).

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 de ruta:

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

Más detalles cubiertos en Tutorial: API de descanso de WordPress - Obtener elementos del menú de navegación

Deepak Rajpal
fuente
Es una buena solución para tener solo una ruta
juanitourquiza
0

No creo que deba usarse un complemento para este tipo de tareas. Además, la respuesta de hkc no es tan mala, solo necesita alguna explicación adicional para que esto funcione con el nav_menu_itemtipo de publicación (la que se usa para los menús de navegación de wp).

Este tipo de publicación ya está registrado y, por lo tanto, debemos modificarlo, esto se hace fácilmente enganchándolo al register_post_type_argsfiltro. Este filtro nos permite cambiar los argumentos para un tipo de publicación específico. El siguiente código muestra exactamente eso para el nav_menu_itemtipo de publicación.

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

Como habrás notado en el código anterior, el código hace un poco más que solo mostrar el tipo de publicación en REST. También altera el controlador REST de publicaciones predeterminado para mostrar una salida algo similar en REST como se describe en la respuesta de Liren . Aunque además de eso, también hace lo que hacen todos los controladores REST de tipo publicación y, por lo tanto, le brinda más control y funcionalidad. También considere esto como una opción más estable ya que no entraría en conflicto con otras rutas REST y, por último, pero no menos importante, también es mucho más conveniente trabajar con él.

Fleuv
fuente
0

Estoy de acuerdo con la respuesta de @Lirens, pero los menús deben llamarse por ID, no por slug. Además, la barra inclinada antes de la ruta del menú no es necesaria. Entonces se convierte en algo más como esto:

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

Así me funcionó.

Sjoerd Oudman
fuente