Ottieni Menu di Navigazione WP dalla REST API V2

20 nov 2015, 23:45:22
Visualizzazioni: 48.1K
Voti: 24

Sto cercando di ottenere il menu di navigazione dalla risposta JSON utilizzando il plugin WP REST API v2.

Non esiste un'estensione del plugin per il menu di navigazione per la REST API v2, ma solo per V1.

Dal codex WordPress Post Types, ho appreso che il menu di navigazione viene trattato come un tipo di post.

Dalla documentazione Rest API, questo è il modo in cui otteniamo i post di un determinato tipo:

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

Ho provato ad ottenerlo in questo modo:

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

Ho ricevuto un errore 403.

{"code":"rest_cannot_read_type","message":"Impossibile visualizzare il tipo.","data":{"status":403}}

il server ha compreso la mia richiesta ma si è rifiutato di fornire i dati.

D: Come posso risolvere questo problema?

1
Commenti

Tutte queste risposte sono semplicemente terribili. Installa questo, estendi quello. Dovrebbe già essere integrato di default, la comunità dovrebbe aprire una issue su GitHub.

SacWebDeveloper SacWebDeveloper
20 dic 2018 03:16:53
Tutte le risposte alla domanda 8
5
74

Dato che a me per primo non piace quando la risposta migliore è "Installa il plugin X", ecco come ho risolto:

Attualmente i menu non sono disponibili nell'API REST di WordPress. Quindi quello che devi fare è registrare il tuo endpoint personalizzato e poi chiamare quella route dall'applicazione che ne ha bisogno.

Dovresti includere qualcosa come questo (nel tuo functions.php, in un plugin, o dove preferisci):

function get_menu() {
    # Cambia 'menu' con lo slug della tua navigazione
    return wp_get_nav_menu_items('menu');
}

add_action( 'rest_api_init', function () {
        register_rest_route( 'myroutes', '/menu', array(
        'methods' => 'GET',
        'callback' => 'get_menu',
    ) );
} );

Per l'esempio sopra potresti accedere ai dati da:

http://tuo-dominio.dev/wp-json/myroutes/menu

Puoi usare il metodo sopra per creare qualsiasi route ti serva per ottenere dati non disponibili nell'API REST di WP. Utile anche se hai bisogno di elaborare alcuni dati prima di inviarli alla tua applicazione.

25 lug 2017 00:20:56
Commenti

grazie per aver condiviso la tua soluzione alternativa, con qualcosa in più del semplice link a un plugin ;-) Sarebbe meglio però prefissare i nomi delle tue funzioni o usare i namespace, per evitare possibili collisioni di nomi, dato che get_menu() è piuttosto generico.

birgire birgire
25 lug 2017 00:30:58

Fantastico, la gente non si rende conto che la maggior parte delle persone ha già dai 30 ai 70 plugin installati. Hanno persino plugin per tenere disattivati gli altri! È pazzesco. Penso che installerò un plugin per mantenere questo thread.

Ignacio Bustos Ignacio Bustos
10 lug 2018 01:49:51

restituisce solo false

moeses moeses
16 nov 2018 22:57:10

@moeses assicurati solo che il nome del menu nelle impostazioni del menu in wp-admin sia lo stesso nome che stai passando come parametro nella funzione wp_get_nav_menu_items

Ângelo Rigo Ângelo Rigo
26 ago 2021 16:43:34

@Liren, c'è un modo per proteggere questa route? in modo che possa essere chiamata solo dai file della mia applicazione WordPress? proteggendola da chiunque possa scoprire la route?

Ângelo Rigo Ângelo Rigo
26 ago 2021 16:45:34
1

La risposta di @Liren funziona bene. Tuttavia, alcuni principianti potrebbero non riuscire a modificare la route. Ecco il codice che funziona bene con WordPress Rest API v2 con modifiche minime.

Sostituisci solo il nome del tuo menu nella funzione wp_get_nav_menu_items(). Se il nome o lo slug del menu non funzionano (restituiscono false), utilizza l'ID del Menu (visibile nel Pannello di controllo durante la modifica del Menu).

function get_my_menu() {
    // Sostituisci con attenzione il nome, lo slug o l'ID del tuo menu
    return wp_get_nav_menu_items('Menu Principale');
}

add_action( 'rest_api_init', function () {
    register_rest_route( 'wp/v2', 'menu', array(
        'methods' => 'GET',
        'callback' => 'get_my_menu',
    ) );
} );

URL della route:

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

Maggiori dettagli sono trattati nel Tutorial: WordPress Rest API – Ottenere gli Elementi del Menu di Navigazione

23 giu 2019 18:30:52
Commenti

È una buona soluzione per avere un solo percorso

juanitourquiza juanitourquiza
23 gen 2020 18:40:59
1

Esiste un'estensione del plugin per il menu di navigazione per l'API REST v2: https://wordpress.org/plugins/wp-api-menus/

28 gen 2016 10:27:09
Commenti

Ho appena visitato il link e ho scoperto che il plugin, purtroppo, non viene aggiornato da 3 anni.

David Gaskin David Gaskin
26 mar 2020 02:48:26
0

Ho optato per il modo più semplice per farlo, mantenendolo comunque dinamico così da poter recuperare più di un menu.

/**
 * Restituisce gli elementi del menu in un array basato sull'ID del menu di navigazione passato
 *
 * @param object La richiesta attuale da cui è possibile accedere ai parametri.
 * @return array Gli elementi del menu contenuti in quel menu specifico
 */
function expose_navigation($request) {
  $id = $request['id'];
  return wp_get_nav_menu_items($id);
}

/**
 * Espone sotto /navigation/{id} gli elementi del menu nell'API wp-json
 *
 * @return void
 */
function expose_navigation_to_rest() {
  register_rest_route( 'wp/v2', '/navigation/(?P<id>\d+)', [
      'methods' => 'GET',
      'callback' => 'expose_navigation'
    ]
  );
}

add_action('rest_api_init', 'expose_navigation_to_rest');

In modo che sia facilmente interrogabile come /navigation/{id}

15 giu 2020 16:51:52
2

Devi aggiungere 'show_in_rest' => true, durante la registrazione del tipo di post.

Vedi dettagli qui http://v2.wp-api.org/extending/custom-content-types/

21 gen 2016 00:00:30
Commenti

register_post_type('nav_menu_item', array('show_in_rest' => true));

luukvhoudt luukvhoudt
28 nov 2019 03:24:46

Sarebbe una grande soluzione, ma per una ragione che non mi è chiara i dati nella risposta non contengono le informazioni del menu, non c'è title, nessuna description o niente di utile (per me) nella risposta. Mi sto perdendo qualcosa?

Johannes Johannes
15 nov 2020 02:37:48
0

Sono d'accordo con la risposta di @Lirens, ma i menu dovrebbero essere chiamati per ID, non per slug. Inoltre, la barra prima del percorso del menu non è necessaria. Quindi diventa qualcosa di più simile a questo:

function get_menu() {
    # Cambia '2' con il tuo ID di navigazione.
    return wp_get_nav_menu_items(2);
}

add_action( 'rest_api_init', function () {
    register_rest_route( 'myroutes', 'menu', array(
        'methods' => 'GET',
        'callback' => 'get_menu',
    ) );
} );

In questo modo ha funzionato per me.

6 mag 2019 18:32:51
0

Non credo che un plugin debba essere utilizzato per questo tipo di attività. Inoltre la risposta di hkc in realtà non è così male, ha solo bisogno di qualche spiegazione aggiuntiva per farla funzionare con il tipo di post nav_menu_item (quello utilizzato per i menu di navigazione di WordPress).

Questo tipo di post è già registrato e quindi dobbiamo modificarlo, cosa che può essere facilmente fatta agganciandosi al filtro register_post_type_args. Questo filtro ci permette di cambiare gli argomenti per un specifico tipo di post. Il codice qui sotto mostra proprio questo per il tipo di post 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' => __( 'Il nome o anche conosciuto come theme_location del menu' ),
                    'type' => 'string',
                ];
                return $query_params;
            }
        }

        // Modifica gli argomenti del tipo di post
        $args['show_in_rest'] = true;
        $args['rest_controller_class'] = 'WP_REST_NavMenuItem_Controller';
    }
    return $args;
}, 10, 2);

Come potresti aver notato dal codice sopra, il codice fa qualcosa in più rispetto al semplice mostrare il tipo di post nella REST. Modifica anche il controller REST predefinito dei post per mostrare un output nella REST simile a quello descritto nella risposta di Liren. Oltre a questo però fa anche tutto ciò che fanno i controller REST dei tipi di post e quindi ti dà più controllo e funzionalità. Considera anche che questa è un'opzione più stabile in quanto non entrerebbe in conflitto con altre route REST e, non meno importante, è anche molto più comoda da utilizzare.

23 nov 2018 12:09:29
0

Puoi ottenere tutti i menu e i dati che sono registrati.

Codice aggiornato:

function get_menu() {
    # Cambia 'menu' con il tuo slug di navigazione personalizzato.
    $menus = wp_get_nav_menus();
    $menuArray = [];
    foreach($menus as $key=>$menu_term){
        $menuArray[] = nav_sort_menu_items(wp_get_nav_menu_items($menu_term->term_id));
    }
    return $menuArray;
}

add_action( 'rest_api_init', function () {
        register_rest_route( 'route', '/menu', array(
        'methods' => 'GET',
        'callback' => 'get_menu',
    ) );
} );

Puoi quindi ottenere i dati da

27 ott 2023 14:49:21