web-dev-qa-db-fra.com

Obtenir WP Menu de navigation de REST API V2

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

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

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

From Rest API Doc , voici comment nous obtenons les posts d'un type:

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

J'ai essayé de l'obtenir comme ça:

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

J'ai reçu 403 erreur.

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

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

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

12
Murhaf Sousli

Il existe une extension de plug-in de menu de navigation pour la REST API v2: https://wordpress.org/plugins/wp-api-menus/

6
Yan Takushevich

Puisque je n'aime pas ça quand la réponse principale est "Installer le plugin X", voici comment je l'ai résolu:

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

Donc, vous incluriez quelque chose comme ceci (dans votre functions.php, le plugin, où que vous soyez):

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 depuis:

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

Vous pouvez utiliser la méthode ci-dessus pour créer les itinéraires de votre choix et obtenir tout type de données non disponible dans WP Rest. Aussi utile si vous devez traiter certaines données avant de les envoyer à votre application.

34
Liren

Je ne pense pas qu'un plugin devrait être utilisé pour ce genre de tâches. Aussi La réponse de hkc n'est en fait pas si mauvaise, il suffit de quelques explications supplémentaires pour que cela fonctionne avec le type de message nav_menu_item (celui utilisé pour les menus de navigation wp).

Ce type de message est déjà enregistré et nous devons donc le modifier. Pour ce faire, il vous suffit de vous connecter au filtre register_post_type_args. Ce filtre nous permet de modifier les arguments d'un type de publication spécifique. Le code ci-dessous montre cela uniquement pour le type d'article 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);

Comme vous l'avez peut-être remarqué dans le code ci-dessus, le code fait un peu plus que simplement afficher le type de publication dans le REST. Il modifie également le contrôleur par défaut Posts REST pour afficher une sortie quelque peu similaire dans le REST décrite dans Réponse de Liren . A côté de cela, il fait aussi ce que font tous les contrôleurs de type post REST et vous donne ainsi plus de contrôle et de fonctionnalités. Considérez également cette option comme une option plus stable, dans la mesure où elle ne serait pas en conflit avec les autres routes REST. Enfin et surtout, elle serait également plus pratique à utiliser.

0
Fleuv

Je suis d’accord avec la réponse de @Lirens, mais les menus doivent être appelés par identifiant et non par slug. De plus, la barre oblique avant le chemin du menu n'est pas nécessaire. Cela devient alors quelque chose de plus semblable à 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 fonctionné pour moi.

0
Sjoerd Oudman

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/

0
hkc