Ottieni il menu di navigazione WP dall'API REST V2


14

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

Non esiste un'estensione del plug-in del menu di navigazione per l'API REST v2 , ma solo per V1.

Dal codice Post Tipi di post di WordPress , ho appreso che il menu di navigazione è trattato come un tipo di post.

Da Rest API Doc , ecco come otteniamo post di un tipo:

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

Ho provato a farlo in questo modo:

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

Ho ricevuto l'errore 403.

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

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

Q: Come posso risolvere questo problema?


Tutte queste risposte sono semplicemente terribili. Installa questo, estendilo. Dovrebbe già essere integrato, la community dovrebbe aprire un problema su GitHub.
SacWebDeveloper il

Risposte:



47

Dato che non mi piace quando la risposta principale è "Installa plug-in X", ecco come l'ho risolto:

I menu non sono attualmente disponibili nel resto WP. Quindi, ciò che devi fare è registrare il tuo endpoint personalizzato e quindi chiamare quella route dall'applicazione che ne ha bisogno.

Quindi includeresti qualcosa del genere (nel tuo Functions.php, plugin, ovunque):

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

Nell'esempio sopra accederai ai dati da:

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

È possibile utilizzare il metodo sopra per creare qualsiasi percorso desiderato per ottenere qualsiasi tipo di dati non disponibile nel resto WP. Buono anche se è necessario elaborare alcuni dati prima di inviarli all'applicazione.


4
grazie per aver condiviso la soluzione alternativa, con più di un semplice collegamento a plugin ;-) Sarebbe meglio però aggiungere il prefisso ai nomi delle funzioni o utilizzare lo spazio dei nomi, per evitare possibili collisioni di nomi, come get_menu()è abbastanza generale.
birgire,

Fantastico, le persone non si rendono conto che la maggior parte delle persone ha già installato da 30 a 70 plugin. Hanno anche plugin per mantenere disattivati ​​gli altri! è pazzo. Penso che installerò un plugin per mantenere questo thread.
Ignacio Bustos,

false
esce

1

La risposta di @Liren funziona bene. Tuttavia, alcuni principianti potrebbero non essere in grado di regolare il percorso. Ecco il codice che funziona bene con WordPress Rest API v2 con modifiche minime.

Sostituisci il nome del tuo menu solo nella funzione wp_get_nav_menu_items () . Se il nome del menu e lo slug non funzionano (Return false), utilizzare l'ID menu (visibile in Dashboard durante la modifica di quel 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 del percorso:

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

Maggiori dettagli trattati in Tutorial: API Rest di WordPress - Ottieni voci di menu di navigazione


È una buona soluzione per avere solo un percorso
juanitourquiza il


0

Non credo che un plug-in debba essere utilizzato per questo tipo di attività. Anche la risposta di hkc non è poi così male, ha solo bisogno di qualche ulteriore spiegazione per farlo funzionare con il nav_menu_itemtipo di post (quello usato per i menu di navigazione di wp).

Questo tipo di post è già registrato e quindi abbiamo bisogno di modificarlo, questo è fatto facilmente agganciandosi al register_post_type_argsfiltro. Questo filtro ci consente di modificare gli argomenti per un tipo di post specifico. Il codice seguente mostra solo quello per il nav_menu_itemtipo di post.

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

Come avrai notato dal codice sopra, il codice fa un po 'di più che mostrare semplicemente il tipo di post nel REST. Altera anche il controller REST Post predefinito per mostrare un output in qualche modo simile nel REST come descritto nella risposta di Liren . Anche se accanto a ciò fa anche quello che fanno tutti i controller REST di tipo post e quindi ti dà più controllo e funzionalità. Considera anche questo come un'opzione più stabile in quanto non sarebbe in conflitto con altre rotte REST e, ultimo ma non meno importante, è anche molto più conveniente lavorare con.


0

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

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

In questo modo ha funzionato per me.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.