Obtenir le menu de navigation WP à partir de l'API REST V2

14

J'essaie d'obtenir le menu de navigation de la réponse JSON en utilisant le plugin WP REST API v2 .

Il n'y a pas d'extension de plugin de menu de navigation pour l'API REST v2 , mais uniquement pour V1.

De Codex WordPress Post Types , j'ai appris que le menu de navigation est traité comme un type de publication.

De Rest API Doc , voici comment nous obtenons des publications d'un type:

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

J'ai essayé de le faire comme ça:

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

J'ai reçu une erreur 403.

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

le serveur a compris ma demande mais a refusé de donner les données.

Q: Comment puis-je résoudre ce problème?

Murhaf Sousli
la source
Toutes ces réponses sont tout simplement terribles. Installez ceci, étendez cela. Il devrait déjà être intégré, la communauté devrait ouvrir un problème sur GitHub.
SacWebDeveloper

Réponses:

47

Comme je ne l'aime pas moi-même lorsque la première réponse est "Installer le plugin X", voici comment je l'ai résolu:

Les menus ne sont actuellement pas disponibles dans WP Rest. Donc, ce que vous devez faire est d' enregistrer votre propre point de terminaison personnalisé , puis d'appeler simplement cette route à partir de votre application qui en a besoin.

Donc, vous incluriez quelque chose comme ça (dans votre functions.php, plugin, n'importe où):

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

Pour l'exemple ci-dessus, vous accéderiez aux données de:

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

Vous pouvez utiliser la méthode ci-dessus pour créer les itinéraires que vous souhaitez pour obtenir tout type de données qui ne sont pas disponibles dans WP Rest. Aussi bien si vous devez traiter certaines données avant de les envoyer à votre application.

Liren
la source
4
merci de partager votre solution de contournement, avec plus qu'un simple lien de plugin ;-) Il serait préférable de préfixer les noms de vos fonctions ou d'utiliser l'espace de noms, pour éviter une éventuelle collision de noms, comme get_menu()c'est assez général.
birgire du
Génial, les gens ne réalisent pas que la plupart des gens ont déjà de 30 à 70 plugins déjà installés. Ils ont même des plugins pour garder les autres désactivés! c'est fou. Je pense que je vais installer un plugin pour garder ce fil.
Ignacio Bustos
il ne produit quefalse
moesphemie
1

La réponse @Liren fonctionne bien. Cependant, peu de débutants peuvent ne pas être en mesure d'ajuster l'itinéraire. Voici le code qui fonctionne bien avec WordPress Rest API v2 avec une modification minimale.

Remplacez votre nom de menu uniquement dans la fonction wp_get_nav_menu_items () . Si le nom et le slug du menu ne fonctionnent pas (Return false), utilisez l'ID de menu (visible dans le tableau de bord lors de la modification de ce 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',
    ) );
} );

URL de l'itinéraire:

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

Plus de détails couverts dans Tutoriel: API WordPress Rest - Obtenir les éléments du menu de navigation

Deepak Rajpal
la source
C'est une bonne solution pour avoir un seul itinéraire
juanitourquiza
0

Vous devez ajouter 'show_in_rest' => true,lors de l'enregistrement du type de publication.

Voir les détails ici http://v2.wp-api.org/extending/custom-content-types/

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

Je ne pense pas qu'un plugin devrait être utilisé pour ce genre de tâches. De plus, la réponse de hkc n'est pas si mauvaise, il n'a besoin que de plus d'explications pour que cela fonctionne avec le nav_menu_itemtype de message (celui utilisé pour les menus de navigation wp).

Ce type de message est déjà enregistré et nous devons donc le modifier, cela se fait facilement en se connectant au register_post_type_argsfiltre. Ce filtre nous permet de modifier les arguments pour un type de message spécifique. Le code ci-dessous montre juste cela pour le nav_menu_itemtype de message.

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

Comme vous l'avez peut-être remarqué dans le code ci-dessus, le code fait un peu plus que simplement afficher le type de message dans le REST. Il modifie également le contrôleur REST Posts par défaut pour afficher une sortie quelque peu similaire dans le REST, comme décrit dans la réponse de Liren . Bien qu'à côté de cela, il fait aussi ce que font tous les contrôleurs REST de type post et vous donne ainsi plus de contrôle et de fonctionnalités. Considérez également cela comme une option plus stable car cela n'entrerait pas en conflit avec d'autres routes REST et enfin et surtout, il est également plus pratique de travailler avec.

Fleuv
la source
0

Je suis d'accord avec la réponse de @Lirens, mais les menus doivent être appelés par ID, pas par slug. En outre, la barre oblique avant le chemin de menu n'est pas nécessaire. Cela devient donc quelque chose de plus comme ceci:

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

Comme ça, ça a marché pour moi.

Sjoerd Oudman
la source