Dapatkan Menu Navigasi WP dari REST API V2

14

Saya mencoba mendapatkan menu navigasi dari respons JSON menggunakan plugin WP REST API v2 .

Tidak ada ekstensi plugin menu navigasi untuk REST API v2 , tetapi hanya untuk V1.

Dari Jenis Tulisan WordPress Post , saya mengetahui bahwa menu navigasi diperlakukan sebagai jenis tulisan.

Dari Rest API Doc , ini adalah cara kami mendapatkan pos tipe:

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

Saya mencoba mendapatkannya seperti ini:

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

Saya menerima 403 kesalahan.

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

server mengerti permintaan saya tetapi menolak untuk memberikan data.

T: Bagaimana saya bisa memperbaikinya?

Murhaf Sousli
sumber
Semua jawaban ini mengerikan. Instal ini, perluas itu. Seharusnya sudah built-in, komunitas harus membuka masalah di GitHub.
SacWebDeveloper

Jawaban:

47

Karena saya tidak suka sendiri ketika jawaban teratas adalah "Instal plugin X", berikut adalah cara saya menyelesaikannya:

Menu saat ini tidak tersedia di WP Rest. Jadi yang perlu Anda lakukan adalah mendaftarkan titik akhir kustom Anda sendiri dan kemudian hanya memanggil rute itu dari aplikasi Anda yang membutuhkannya.

Jadi Anda akan memasukkan sesuatu seperti ini (di functions.php Anda, plugin, di mana saja):

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

Untuk contoh di atas Anda akan mengakses data dari:

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

Anda dapat menggunakan metode di atas untuk membuat rute yang Anda inginkan untuk mendapatkan semua jenis data yang tidak tersedia di WP Rest. Juga bagus jika Anda perlu memproses beberapa data sebelum mengirimnya ke aplikasi Anda.

Liren
sumber
4
terima kasih telah berbagi solusi Anda, dengan lebih dari sekadar tautan plugin ;-) Akan lebih baik jika Anda awali nama fungsi Anda atau menggunakan namespace, untuk menghindari kemungkinan tabrakan nama, seperti get_menu()yang cukup umum.
birgire
Hebat, orang tidak menyadari bahwa sebagian besar orang sudah dari 30 hingga 70 plugin sudah diinstal. Mereka bahkan memiliki plugin untuk tetap menonaktifkan orang lain! ini gila. Saya pikir saya akan menginstal plugin untuk menjaga utas ini.
Ignacio Bustos
ini hanya menghasilkanfalse
moesphemie
1

Jawaban @Liren bekerja dengan baik. Namun beberapa pemula mungkin tidak dapat menyesuaikan rute. Berikut adalah kode yang berfungsi dengan baik dengan WordPress Rest API v2 dengan modifikasi minimum.

Ganti nama menu Anda hanya dalam fungsi wp_get_nav_menu_items () . Jika nama menu dan siput tidak berfungsi (Return false), gunakan Menu ID (terlihat di Dashboard saat mengedit Menu itu).

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

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

Rincian lebih lanjut tercakup dalam Tutorial: WordPress Rest API - Dapatkan Item Menu Navigasi

Deepak Rajpal
sumber
Ini solusi yang bagus karena hanya memiliki satu rute
juanitourquiza
0

Anda perlu menambahkan 'show_in_rest' => true,saat mendaftar jenis posting.

Lihat detailnya di sini http://v2.wp-api.org/extending/custom-content-types/

hkc
sumber
register_post_type('nav_menu_item', array('show_in_rest' => true));
Fleuv
0

Saya tidak berpikir plugin harus digunakan untuk tugas-tugas semacam ini. Juga jawaban hkc sebenarnya tidak terlalu buruk, hanya perlu penjelasan lebih lanjut untuk membuat ini bekerja dengan nav_menu_itemjenis posting (yang digunakan untuk menu navigasi wp).

Jenis posting ini sudah terdaftar dan dengan demikian kita perlu mengubahnya, ini mudah dilakukan dengan menghubungkan ke register_post_type_argsfilter. Filter ini memungkinkan kita untuk mengubah argumen untuk jenis posting tertentu. Kode di bawah ini menunjukkan hal itu untuk nav_menu_itemjenis posting.

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

Seperti yang mungkin Anda perhatikan dari kode di atas, kode tersebut sedikit lebih dari sekadar menampilkan jenis posting di REST. Ini juga mengubah controller Posting REST default untuk menampilkan output yang agak mirip di REST seperti yang dijelaskan dalam jawaban Liren . Meskipun di samping itu juga melakukan apa yang semua pengontrol REST jenis posting lakukan dan dengan demikian memberi Anda lebih banyak kontrol dan fungsionalitas. Juga pertimbangkan ini sebagai opsi yang lebih stabil karena tidak akan bertentangan dengan rute REST lainnya dan yang tak kalah pentingnya, ini juga jauh lebih nyaman untuk digunakan.

Fleuv
sumber
0

Saya setuju dengan jawaban @Lirens, tetapi menu harus dipanggil dengan ID, bukan siput. Juga, garis miring sebelum jalur menu tidak diperlukan. Jadi itu menjadi sesuatu yang lebih seperti ini:

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

Seperti ini, ini berhasil untuk saya.

Sjoerd Oudman
sumber