Menambahkan Bidang Ke Item Menu WordPress – Plugin Kustom

Diterbitkan: 2021-05-19

Dalam artikel sebelumnya kami melihat bagaimana Anda dapat menambahkan bidang khusus Anda sendiri ke item menu menggunakan kait tindakan wp_nav_menu_item_custom_fields yang diperkenalkan di WordPress 5.4. Kami merinci dua rute untuk mencapai ini; dengan menambahkan beberapa kode kustom ke functions.php atau dengan menggunakan plugin WordPress.

Pada artikel ini, kita akan membuat ulang bidang yang sama tetapi kali ini kita akan melakukannya dengan membuat plugin sendiri dari awal.

Mari kita mulai.

Pembuatan Plugin

Kami tidak akan membahas detail dasar pembuatan plugin WordPress karena ini telah dibahas dalam artikel mendalam kami 'Cara Membuat Plugin WordPress Pertama Anda. Panduan Langkah-demi-Langkah'. Kami akan langsung membuat folder plugin di bawah folder wp-content/plugin/ . Selanjutnya kita akan memberi nama folder plugin kustom kita “menu-item-field-creator” dan di dalamnya kita akan membuat file bernama menu-item-field-creator.php .

Setelah ini kita akan membuka file ini dengan editor teks favorit kita dan menambahkan kode di bawah ini. Kode ini memiliki efek memperkenalkan plugin ke inti WordPress.

 <?php /* Plugin Name: Menu Item Field Creator Description: My custom plugin to create menu item fields */

Seperti yang mungkin Anda perhatikan, kami mendefinisikan nama dan deskripsi plugin seperti yang kami inginkan untuk ditampilkan di area plugin admin. Demi contoh ini, kami tidak akan mendefinisikan bidang header lainnya.

Setelah langkah-langkah ini selesai, mari menuju ke bagian Plugin di area Admin dan periksa apakah plugin ditampilkan dengan benar.

Selanjutnya, kita akan memasukkan kode fungsional pertama kita yang akan membentuk kelas utama kita dan beberapa fungsi.

Cara Sederhana

Cara paling sederhana untuk membuat plugin ini berfungsi adalah dengan memasukkan kode yang kita tulis di artikel sebelumnya ke dalam file PHP utama plugin sehingga konten akhir terlihat seperti ini:

 <?php /* Plugin Name: Menu Item Field Creator Description: My custom plugin to create menu item fields */ /** * Add the field. */ function pr_menu_item_sub( $item_id, $item ) { $menu_item_sub = get_post_meta( $item_id, '_menu_item_sub', true ); ?> <div> <span class="subtitle"><?php _e( 'Subtitle', 'menu-item-sub' ); ?></span><br /> <input type="hidden" class="nav-menu-id" value="<?php echo $item_id; ?>" /> <div class="logged-input-holder"> <input type="text" name="menu_item_sub[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $menu_item_sub ); ?>" /> </div> </div> <?php } add_action( 'wp_nav_menu_item_custom_fields', 'pr_menu_item_sub', 10, 2 ); /** * Save input. */ function save_menu_item_sub( $menu_id, $menu_item_db_id ) { if ( isset( $_POST['menu_item_sub'][ $menu_item_db_id ] ) ) { $sanitized_data = sanitize_text_field( $_POST['menu_item_sub'][ $menu_item_db_id ] ); update_post_meta( $menu_item_db_id, '_menu_item_sub', $sanitized_data ); } else { delete_post_meta( $menu_item_db_id, '_menu_item_sub' ); } } add_action( 'wp_update_nav_menu_item', 'save_menu_item_sub', 10, 2 ); /** * Show the Menu Field Value. */ function show_menu_item_sub( $title, $item ) { if ( is_object( $item ) && isset( $item->ID ) ) { $menu_item_sub = get_post_meta( $item->ID, '_menu_item_sub', true ); if ( ! empty( $menu_item_sub ) ) { $title .= '<p class="menu-item-sub">' . $menu_item_sub . '</p>'; } } return $title; } add_filter( 'nav_menu_item_title', 'show_menu_item_sub', 10, 2 );

Pada titik ini, jika Anda mengaktifkan plugin, Anda akan menemukan ini berfungsi dengan baik. Namun ada cara untuk mencapai hasil yang sama menggunakan gaya pengkodean yang berbeda.

Menggunakan Pemrograman Berorientasi Objek

Untuk mencapai hasil yang sama dalam pendekatan yang lebih Berorientasi Objek, seperti yang kami jelaskan di artikel terkait kami, ikuti petunjuk di bawah ini.

Untuk memulai, kosongkan konten file PHP utama plugin Anda, kecuali dari komentar header dan masukkan baris berikut:

 class MyCP_Menu_Item_Field_Creator { } $mycp_menu_item_field_creator = new MyCP_Menu_Item_Field_Creator();

Apa yang telah kita lakukan dengan kode ini sejauh ini adalah untuk mendefinisikan kelas pembungkus MyCP_Menu_Item_Field_Creator yang akan berisi seluruh fungsionalitas. Terakhir, kami membuat instance objek.

Sangat penting untuk diingat bahwa nama kelas utama yang Anda tentukan akan tersedia secara global dan oleh karena itu Anda harus memastikan itu unik dan tidak ada kemungkinan plugin atau tema lain menggunakan nama yang sama. Itulah mengapa Anda disarankan untuk menggunakan awalan khusus seperti MyCP_ yang kami gunakan di atas.

Di dalam kelas kita sekarang akan menambahkan beberapa fungsi. Konten akhir dari file PHP utama plugin kami akan terlihat seperti ini:

 <?php /* Plugin Name: Menu Item Field Creator Description: My custom plugin to create menu item fields */ class MyCP_Menu_Item_Field_Creator { public function __construct() { add_action( 'wp_nav_menu_item_custom_fields', array( $this, 'menu_item_sub' ), 10, 2 ); add_action( 'wp_update_nav_menu_item', array( $this, 'save_menu_item_sub' ), 10, 2 ); add_action( 'nav_menu_item_title', array( $this, 'show_menu_item_sub' ), 10, 2 ); } public function menu_item_sub( $item_id, $item ) { $menu_item_sub = get_post_meta( $item_id, '_menu_item_sub', true ); ?> <div> <span class="subtitle"><?php _e( 'Subtitle', 'menu-item-sub' ); ?></span><br /> <input type="hidden" class="nav-menu-id" value="<?php echo $item_id; ?>" /> <div class="logged-input-holder"> <input type="text" name="menu_item_sub[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $menu_item_sub ); ?>" /> </div> </div> <?php } public function save_menu_item_sub( $menu_id, $menu_item_db_id ) { if ( isset( $_POST['menu_item_sub'][ $menu_item_db_id ] ) ) { $sanitized_data = sanitize_text_field( $_POST['menu_item_sub'][ $menu_item_db_id ] ); update_post_meta( $menu_item_db_id, '_menu_item_sub', $sanitized_data ); } else { delete_post_meta( $menu_item_db_id, '_menu_item_sub' ); } } public function show_menu_item_sub( $title, $item ) { if ( is_object( $item ) && isset( $item->ID ) ) { $menu_item_sub = get_post_meta( $item->ID, '_menu_item_sub', true ); if ( ! empty( $menu_item_sub ) ) { $title .= '<p class="menu-item-sub">' . $menu_item_sub . '</p>'; } } return $title; } } $mycp_menu_item_field_creator = new MyCP_Menu_Item_Field_Creator();

Kami menghapus awalan dari nama metode karena kami sekarang memiliki awalan kelas.

Dalam fungsi __construct kami mendefinisikan kait yang kami gunakan bersama dengan fungsi panggilan baliknya yang akan dijalankan. Selanjutnya kita memperkenalkan fungsi callback menu_item_sub yang akan menampilkan field input dimana user admin dapat mengisi subtitle item.

Setelah ini, kami menyimpan input dengan metode save_menu_item_sub dan akhirnya, dengan callback show_menu_item_sub , kami menampilkan nilainya, jika tersedia, di menu front-end.

Memperluas Walker

Dalam contoh di atas, kami menyertakan bidang menu khusus di dalam judul item menu, tanpa mengubah output HTML dari data pohon menu. Tetapi bagaimana jika kita ingin menambahkan bidang subtitle sebagai elemen HTML terpisah seperti elemen <div> di luar tautan elemen judul?

Di sinilah kita harus bekerja sekali lagi dengan kelas Walker. Seperti yang kita lihat di artikel 'Mendapatkan Familiar dengan Kelas Walker WordPress', dengan memperluas Walker Anda dapat menyesuaikan struktur data seperti pohon. Dalam hal ini akan menjadi menu.

Ini berarti tentu saja kita hanya perlu mengubah kode kita yang terkait dengan tampilan front-end bidang kustom kita. Jadi mari kita pergi dan mengganti seluruh kode dengan yang ini:

 <?php /* Plugin Name: Menu Item Field Creator Description: My custom plugin to create menu item fields */ class MyCP_Menu_Item_Field_Creator { public function __construct() { add_action( 'wp_nav_menu_item_custom_fields', array( $this, 'menu_item_sub' ), 10, 2 ); add_action( 'wp_update_nav_menu_item', array( $this, 'save_menu_item_sub' ), 10, 2 ); add_filter( 'wp_nav_menu_args', array( $this, 'menu_item_sub_custom_walker' ) ); } public function menu_item_sub( $item_id, $item ) { $menu_item_sub = get_post_meta( $item_id, '_menu_item_sub', true ); ?> <div> <span class="subtitle"><?php _e( 'Subtitle', 'menu-item-sub' ); ?></span><br /> <input type="hidden" class="nav-menu-id" value="<?php echo $item_id; ?>" /> <div class="logged-input-holder"> <input type="text" name="menu_item_sub[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $menu_item_sub ); ?>" /> </div> </div> <?php } public function save_menu_item_sub( $menu_id, $menu_item_db_id ) { if ( isset( $_POST['menu_item_sub'][ $menu_item_db_id ] ) ) { $sanitized_data = sanitize_text_field( $_POST['menu_item_sub'][ $menu_item_db_id ] ); update_post_meta( $menu_item_db_id, '_menu_item_sub', $sanitized_data ); } else { delete_post_meta( $menu_item_db_id, '_menu_item_sub' ); } } public function menu_item_sub_custom_walker( $args ) { if ( class_exists( 'My_Custom_Nav_Walker' ) ) { $args['walker'] = new My_Custom_Nav_Walker(); } else { echo 'DOES NOT EXIST'; } return $args; } } $mycp_menu_item_field_creator = new MyCP_Menu_Item_Field_Creator(); if ( ! class_exists( 'My_Custom_Nav_Walker' ) ) { class My_Custom_Nav_Walker extends Walker_Nav_Menu { public function start_el( &$output, $item, $depth=0, $args=[], $id=0 ) { $menu_item_sub = get_post_meta( $item->ID, '_menu_item_sub', true ); $output .= '<li class="' . implode( ' ', $item->classes ) . '">'; if ( $item->url && $item->url != '#' ) { $output .= '<a href="' . $item->url . '">'; } else { $output .= '<span>'; } $output .= $item->title; if ( $item->url && $item->url != '#' ) { $output .= '</a>'; } else { $output .= '</span>'; } if ( ! empty( $menu_item_sub ) ) { $output .= '<div class="menu-item-sub">' . $menu_item_sub . '</div>'; } } } }

Anda mungkin telah memperhatikan bahwa kami menghapus metode show_menu_item_sub dan bekerja dengan struktur item menu front-end secara berbeda. Kami memperkenalkan kelas Walker kustom kami My_Custom_Nav_Walker di luar kelas utama kami dan melalui metode menu_item_sub_custom_walker kami, kami mengubah nilai default untuk argumen 'walker' menjadi My_Custom_Nav_Walker . Dengan cara ini output HTML menu yang kami sediakan di Walker kustom kami akan diterapkan di ujung depan kami.

Mari kita periksa hasilnya.

Seperti yang kita lihat, deskripsi kita kali ini ditempatkan di luar href dari tautan item menu seperti yang kita maksudkan.

Mengambilnya Lebih Jauh

Sebelum kita menyelesaikan ini, perlu disebutkan bahwa kita sengaja menggunakan contoh “Subtitle” karena mudah dilakukan dan dipahami.

Jika Anda ingin memaksakan diri, kami sarankan Anda membuat skenario sendiri untuk bereksperimen. Coba misalnya untuk membuat output berbeda yang memungkinkan pengguna Admin menentukan peran pengguna mana yang diizinkan untuk melihat item menu.

Sebagai petunjuk awal, kami akan memberi Anda hasilnya. Ganti metode keluaran saat ini (ditunjukkan di bawah)

 function menu_item_sub( $item_id, $item ) { $menu_item_sub = get_post_meta( $item_id, '_menu_item_sub', true ); ?> <div> <span class="subtitle"><?php _e( 'Subtitle', 'menu-item-sub' ); ?></span><br /> <input type="hidden" class="nav-menu-id" value="<?php echo $item_id; ?>" /> <div class="logged-input-holder"> <input type="text" name="menu_item_sub[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $menu_item_sub ); ?>" /> </div> </div> <?php }

dengan yang ini:

 function PREFIX_Menu_Item_Roles() { global $wp_roles; $display_roles = apply_filters( 'nav_menu_roles', $wp_roles->role_names ); if ( ! $display_roles ) return; ?> <p class="field-nav_menu_logged_in_out nav_menu_logged_in_out nav_menu_logged_in_out-thin"> <fieldset> <legend><?php _e( 'Display Mode', 'nav-menu-roles' ); ?></legend> <label for="edit-menu-item-role_logged_in"> <input type="radio" class="edit-menu-item-logged_in_out" value="in" name="menu-item-role_logged_in" /> <?php _e( 'Logged In Users', 'nav-menu-roles' ); ?><br/> </label> <label for="edit-menu-item-role_logged_out"> <input type="radio" class="edit-menu-item-logged_in_out" value="out" name="menu-item-role_logged_out" /> <?php _e( 'Logged Out Users', 'nav-menu-roles' ); ?><br/> </label> <label for="edit-menu-item-role_everyone"> <input type="radio" class="edit-menu-item-logged_in_out" value="" name="menu-item-role_everyone" /> <?php _e( 'Everyone', 'nav-menu-roles' ); ?><br/> </label> </fieldset> </p> <?php }

Sekarang coba buat metode yang menyimpan perubahan bersama dengan metode yang menampilkan nilai saat ini/yang disimpan menggunakan kait yang benar.

Kesimpulan

Menyesuaikan menu WordPress bisa membuat frustasi sampai Anda mengetahui alat yang tersedia untuk Anda lakukan ini. Semoga artikel ini memberi Anda beberapa wawasan tentang apa yang mungkin dicapai dan cara-cara yang dapat Anda lakukan untuk menerapkan tugas-tugas seperti ini.

Lihat juga

  • Menambahkan Bidang Kustom ke Item Menu WordPress