Obtenha o menu de navegação WP da API REST V2


14

Estou tentando obter o menu de navegação da resposta JSON usando o plug-in WP REST API v2 .

Não há extensão de plug-in de menu de navegação para a API REST v2 , mas apenas para V1.

No codex WordPress Post Types , aprendi que o menu de navegação é tratado como um tipo de postagem.

No Rest API Doc , é assim que obtemos postagens de um tipo:

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

Eu tentei fazê-lo assim:

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

Eu recebi o erro 403.

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

o servidor entendeu minha solicitação, mas se recusou a fornecer os dados.

P: Como posso corrigir isso?


Todas essas respostas são simplesmente terríveis. Instale isso, estenda isso. Ele já deve estar incorporado, a comunidade deve abrir um problema no GitHub.
SacWebDeveloper

Respostas:



47

Como eu não gosto quando a resposta principal é "Install plugin X", eis como eu o resolvi:

No momento, os menus não estão disponíveis no WP Rest. Portanto, o que você precisa fazer é registrar seu próprio ponto de extremidade personalizado e chamar a rota a partir do aplicativo que precisa.

Então você incluiria algo assim (no seu functions.php, plugin, qualquer lugar):

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 o exemplo acima, você acessaria os dados de:

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

Você pode usar o método acima para criar as rotas que desejar para obter qualquer tipo de dados que não esteja disponível no WP Rest. Também é bom se você precisar processar alguns dados antes de enviá-los para o seu aplicativo.


4
obrigado por compartilhar sua solução alternativa, com mais do que apenas um link de plug-in ;-) Seria melhor prefixar os nomes das funções ou usar o namespace, para evitar uma possível colisão de nomes, como get_menu()é bastante geral.
birgire

Incrível, as pessoas não percebem que a maioria das pessoas já possui de 30 a 70 plug-ins já instalados. Eles ainda têm plugins para manter os outros desativados! isso é loucura. Eu acho que vou instalar um plugin para manter este segmento.
Ignacio Bustos

ele faz apenas saídafalse
moesphemie

1

A resposta @Liren funciona bem. No entanto, poucos iniciantes podem não conseguir ajustar a rota. Aqui está o código que funciona bem com a WordPress Rest API v2 com modificação mínima.

Substitua o nome do menu apenas na função wp_get_nav_menu_items () . Se o nome e o slug do menu não funcionarem (Return false), use o ID do menu (visível no Dashboard ao editar esse 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 rota:

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

Mais detalhes abordados no Tutorial: API de descanso do WordPress - obter itens de menu de navegação


É uma boa solução para ter apenas uma rota
juanitourquiza 23/01


0

Eu não acho que um plugin deva ser usado para esse tipo de tarefa. Além disso, a resposta do hkc não é tão ruim assim, é necessária apenas mais explicações para fazer esse trabalho funcionar com o nav_menu_itemtipo de post (o usado para os menus de navegação wp).

Esse tipo de post já está registrado e, portanto, precisamos alterá-lo, isso é facilmente feito conectando-o ao register_post_type_argsfiltro. Esse filtro nos permite alterar os argumentos para um tipo de postagem específico. O código abaixo mostra exatamente isso para o nav_menu_itemtipo de postagem.

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 você deve ter notado no código acima, o código faz um pouco mais do que apenas mostrar o tipo de postagem no REST. Ele também altera o controlador Posts REST padrão para mostrar uma saída um pouco semelhante no REST, conforme descrito na resposta de Liren . Embora próximo disso, ele também faça o que todos os controladores REST do tipo pós fazem e, portanto, oferece mais controle e funcionalidade. Considere também isso como uma opção mais estável, pois não entraria em conflito com outras rotas REST e, por último, mas não menos importante, também é muito mais conveniente trabalhar.


0

Concordo com a resposta do @Lirens, mas os menus devem ser chamados por ID, não por slug. Além disso, a barra antes do caminho do menu não é necessária. Portanto, torna-se algo mais parecido com isto:

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

Assim funcionou para mim.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.