Obține Meniul de Navigare WP din REST API V2

20 nov. 2015, 23:45:22
Vizualizări: 48.1K
Voturi: 24

Încerc să obțin meniul de navigare din răspunsul JSON folosind plugin-ul WP REST API v2.

Nu există o extensie pentru meniul de navigare pentru REST API v2, ci doar pentru V1.

Din codex-ul WordPress Post Types, am aflat că meniul de navigare este tratat ca un tip de postare.

Din Documentația Rest API, așa putem obține postări de un anumit tip:

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

Am încercat să-l obțin astfel:

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

Am primit eroarea 403.

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

serverul a înțeles cererea mea dar a refuzat să furnizeze datele.

Î: Cum pot rezolva această problemă?

1
Comentarii

Toate aceste răspunsuri sunt pur și simplu groaznice. Instalează asta, extinde cealaltă. Ar trebui să fie deja încorporat, comunitatea ar trebui să deschidă o problemă pe GitHub.

SacWebDeveloper SacWebDeveloper
20 dec. 2018 03:16:53
Toate răspunsurile la întrebare 8
5
74

Deoarece nici mie nu-mi place când răspunsul principal este "Instalează pluginul X", iată cum am rezolvat eu problema:

În prezent, meniurile nu sunt disponibile în WP REST. Deci, ceea ce trebuie să faci este să înregistrezi propriul endpoint personalizat și apoi să apelezi acea rută din aplicația ta care are nevoie de ea.

Așadar, ai putea include ceva de genul acesta (în functions.php, într-un plugin, oriunde):

function get_menu() {
    # Schimbă 'menu' cu slug-ul tău personalizat pentru navigare.
    return wp_get_nav_menu_items('menu');
}

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

Pentru exemplul de mai sus, ai putea accesa datele de la:

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

Poți folosi metoda de mai sus pentru a crea orice rute dorești pentru a obține orice tip de date care nu sunt disponibile în WP REST. De asemenea, este utilă dacă ai nevoie să prelucrezi unele date înainte de a le trimite către aplicația ta.

25 iul. 2017 00:20:56
Comentarii

mulțumesc pentru că ai împărtășit soluția ta, nu doar un simplu link către un plugin ;-) Ar fi mai bine totuși să prefixezi numele funcțiilor tale sau să folosești un namespace, pentru a evita posibile coliziuni de nume, deoarece get_menu() este destul de generic.

birgire birgire
25 iul. 2017 00:30:58

Uimitor, oamenii nu realizează că majoritatea au deja între 30 și 70 de pluginuri instalate. Unii chiar au pluginuri pentru a ține altele dezactivate! E nebunie. Cred că o să instalez un plugin pentru a păstra acest thread.

Ignacio Bustos Ignacio Bustos
10 iul. 2018 01:49:51

doar returnează false

moeses moeses
16 nov. 2018 22:57:10

@moeses doar asigură-te că numele meniului în setările de meniu din wp-admin este același cu numele pe care îl transmiți ca parametru în funcția wp_get_nav_menu_items

Ângelo Rigo Ângelo Rigo
26 aug. 2021 16:43:34

@Liren, există vreo modalitate prin care pot proteja această rută? astfel încât să pot apela doar din fișierele aplicației mele WordPress? protejând-o de oricine ar putea descoperi ruta?

Ângelo Rigo Ângelo Rigo
26 aug. 2021 16:45:34
1

Răspunsul lui @Liren funcționează bine. Cu toate acestea, câțiva începători s-ar putea să nu fie capabili să ajusteze ruta. Iată codul care funcționează bine cu WordPress Rest API v2 cu modificări minime.

Înlocuiți doar numele meniului în funcția wp_get_nav_menu_items(). Dacă numele meniului și slug-ul nu funcționează (Returnează false), utilizați ID-ul Meniului (vizibil în Panoul de control în timpul editării acelui Meniu).

function get_my_menu() {
    // Înlocuiți cu atenție numele, slug-ul sau ID-ul meniului dvs.
    return wp_get_nav_menu_items('Navigare Principală');
}

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

URL-ul rutei:

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

Mai multe detalii sunt acoperite în Tutorialul: WordPress Rest API – Obțineți Elemente din Meniul de Navigare

23 iun. 2019 18:30:52
Comentarii

Este o soluție bună pentru a avea o singură rută

juanitourquiza juanitourquiza
23 ian. 2020 18:40:59
1

Există o extensie de plugin pentru meniul de navigare pentru REST API v2: https://wordpress.org/plugins/wp-api-menus/

28 ian. 2016 10:27:09
Comentarii

Tocmai am vizitat linkul și am descoperit că pluginul, din păcate, nu a fost actualizat de 3 ani.

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

Am ales cea mai simplă metodă de a face acest lucru, păstrând totuși dinamica pentru a putea prelua mai multe meniuri.

/**
 * Returnează elementele de meniu într-un array bazat pe ID-ul meniului de navigare transmis
 *
 * @param object Cererea actuală unde pot fi accesate parametrii.
 * @return array Elementele de meniu conținute în acel meniu specific
 */
function expose_navigation($request) {
  $id = $request['id'];
  return wp_get_nav_menu_items($id);
}

/**
 * Expune sub /navigation/{id} elementele de meniu în API-ul 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');

Astfel, poate fi interogat ușor folosind /navigation/{id}

15 iun. 2020 16:51:52
2

Trebuie să adaugi 'show_in_rest' => true, în timpul înregistrării tipului de postare.

Vezi detalii aici http://v2.wp-api.org/extending/custom-content-types/

21 ian. 2016 00:00:30
Comentarii

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

luukvhoudt luukvhoudt
28 nov. 2019 03:24:46

Acesta ar fi o soluție excelentă, dar dintr-un motiv care nu-mi este evident, datele din răspuns nu conțin informațiile despre meniu, nu există niciun title, nici description sau orice altceva util (pentru mine) în răspuns. Omiteam ceva?

Johannes Johannes
15 nov. 2020 02:37:48
0

Sunt de acord cu răspunsul lui @Lirens, dar meniurile ar trebui apelate după ID, nu după slug. De asemenea, slash-ul înaintea căii meniului nu este necesar. Deci codul ar trebui să arate cam așa:

function get_menu() {
    # Schimbă '2' cu ID-ul tău de navigare.
    return wp_get_nav_menu_items(2);
}

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

Așa a funcționat pentru mine.

6 mai 2019 18:32:51
0

Nu cred că ar trebui folosit un plugin pentru acest tip de sarcini. De asemenea, răspunsul lui hkc nu este chiar atât de rău, are nevoie doar de o explicație suplimentară pentru a funcționa cu tipul de postare nav_menu_item (cel folosit pentru meniurile de navigare WordPress).

Acest tip de postare este deja înregistrat, așa că trebuie să-l modificăm, ceea ce se poate face ușor prin conectarea la filtrul register_post_type_args. Acest filtru ne permite să schimbăm argumentele pentru un anumit tip de postare. Codul de mai jos arată exact acest lucru pentru tipul de postare 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' => __( 'Numele sau theme_location-ul meniului' ),
                    'type' => 'string',
                ];
                return $query_params;
            }
        }

        // Modifică argumentele tipului de postare
        $args['show_in_rest'] = true;
        $args['rest_controller_class'] = 'WP_REST_NavMenuItem_Controller';
    }
    return $args;
}, 10, 2);

După cum probabil ați observat din codul de mai sus, acesta face ceva mai mult decât doar afișarea tipului de postare în REST. De asemenea, modifică controllerul REST implicit pentru Posts pentru a afișa un rezultat similar în REST cu cel descris în răspunsul lui Liren. Pe lângă asta, oferă toată funcționalitatea unui controller REST pentru tipuri de postare, oferind mai mult control. De asemenea, aceasta este o opțiune mai stabilă care nu intră în conflict cu alte rute REST și, nu în ultimul rând, este mult mai convenabil de lucrat cu ea.

23 nov. 2018 12:09:29
0

Puteți obține toate meniurile și datele care sunt înregistrate.

Cod actualizat:

function get_menu() {
    # Schimbați 'menu' cu propriul dumneavoastră slug de navigare.
    $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',
    ) );
} );

Apoi puteți obține datele de la

27 oct. 2023 14:49:21