3 Pendekatan Untuk Menambahkan Bidang yang Dapat Dikonfigurasi Ke Plugin WordPress Anda
Diterbitkan: 2022-03-10Siapa pun yang telah membuat plugin WordPress memahami kebutuhan untuk membuat bidang yang dapat dikonfigurasi untuk mengubah cara kerja plugin. Ada banyak sekali kegunaan untuk opsi yang dapat dikonfigurasi dalam sebuah plugin , dan hampir banyak cara untuk mengimplementasikan opsi tersebut. Soalnya, WordPress memungkinkan pembuat plugin untuk membuat markup mereka sendiri di dalam halaman pengaturan mereka. Sebagai efek samping, halaman pengaturan dapat sangat bervariasi antar plugin.
Pada artikel ini kita akan membahas tiga cara umum untuk membuat plugin Anda dapat dikonfigurasi. Kami akan mulai dengan membuat halaman pengaturan dan membuat bidang kami menggunakan API Pengaturan WordPress default.
Bacaan Lebih Lanjut tentang SmashingMag:
- Perluas WordPress Dengan Bidang Kustom
- Peretasan Bidang Kustom Untuk WordPress
- Memperluas Bidang Kustom Tingkat Lanjut Dengan Kontrol Anda Sendiri
- Panduan Lengkap Untuk Jenis Posting Kustom
Saya kemudian akan memandu Anda melalui cara mengatur bidang Anda dengan penangan khusus. Terakhir, saya akan menunjukkan kepada Anda bagaimana mengintegrasikan plugin bidang yang dapat dikonfigurasi, Bidang Kustom Lanjutan (ACF) ke dalam plugin Anda sendiri.
Karena ini adalah posting yang panjang, berikut adalah daftar isi dengan tautan ke masing-masing bagian utama:
- Membuat Halaman Plugin dan Pengaturan kami
- Pendekatan 1: Menggunakan Fungsionalitas WordPress Bawaan
- Pendekatan 2: Menyiapkan Formulir dan Handler Kustom
- Pendekatan 3: Mengintegrasikan ACF (Bidang Kustom Lanjutan) Ke dalam Plugin Anda
Untuk contoh kode, silakan lihat repositori yang telah saya siapkan untuk menyertai posting ini.
Membuat Halaman Plugin Dan Pengaturan Kami
Hal pertama yang perlu kita lakukan adalah mengatur plugin kita dan membuat halaman pengaturan. Ketiga pendekatan yang diuraikan dalam artikel ini dimulai dengan struktur plugin di bawah ini. Struktur plugin ini berorientasi objek sehingga mungkin ada beberapa perbedaan dalam kode Anda sendiri jika plugin Anda ditulis secara prosedural. Berikan perhatian khusus pada format fungsi panggilan balik dalam tindakan dan filter.
/* Plugin Name: Smashing Fields Plugin description: >- Setting up configurable fields for our plugin. Author: Matthew Ray Version: 1.0.0 */ class Smashing_Fields_Plugin { // Our code will go here } new Smashing_Fields_Plugin();
Di dalam kelas kami, kami akan menambahkan kait tindakan untuk menambahkan halaman pengaturan:
public function __construct() { // Hook into the admin menu add_action( 'admin_menu', array( $this, 'create_plugin_settings_page' ) ); }
Anda dapat melihat bahwa panggilan balik tindakan kami adalah create_plugin_settings_page
, jadi mari buat metode itu. Catatan: Saya telah menyiapkan argumen sebagai variabel bernama terpisah untuk memberikan beberapa konteks pada kode kita, tetapi Anda dapat menempatkan nilai secara langsung dalam fungsi untuk menghemat memori.
public function create_plugin_settings_page() { // Add the menu item and page $page_title = 'My Awesome Settings Page'; $menu_title = 'Awesome Plugin'; $capability = 'manage_options'; $slug = 'smashing_fields'; $callback = array( $this, 'plugin_settings_page_content' ); $icon = 'dashicons-admin-plugins'; $position = 100; add_menu_page( $page_title, $menu_title, $capability, $slug, $callback, $icon, $position ); }
Lihatlah codex WP untuk add_menu_page
untuk informasi lebih lanjut.
Fungsi ini akan membuat halaman kita serta item menu. Bagian penting di sini adalah argumen siput, kemampuan, dan panggilan balik. Siput yang akan kita gunakan nanti untuk mendaftarkan bidang kita, jadi tuliskan itu di suatu tempat. Anda dapat mengubah kemampuan untuk mengizinkan tingkat pengguna yang berbeda mengakses halaman pengaturan Anda. Untuk callback, kita akan segera membuat metode tersebut. Perhatikan Anda juga dapat menempatkan kelas tanda hubung langsung ke fungsi untuk mengubah ikon menu. Argumen terakhir adalah posisi item menu di dalam menu; bermain-main dengan nomor ini untuk menemukan tempat di menu Anda ingin pengaturan Anda jatuh. Catatan: Anda dapat menggunakan nilai desimal untuk menghindari konflik dengan item menu lainnya.
Langkah kita selanjutnya adalah membuat metode callback plugin_settings_page_content
untuk halaman pengaturan kita.
public function plugin_settings_page_content() { echo 'Hello World!'; }
Jika Anda menyimpan plugin dan menyegarkan panel admin WordPress, Anda akan melihat yang berikut:

Anda dapat melihat bahwa halaman pengaturan Anda adalah item menu tingkat atas. Anda mungkin lebih suka membiarkannya seperti ini berdasarkan kebutuhan halaman pengaturan Anda. Namun, Anda mungkin juga ingin memiliki pengaturan plugin di bawah item menu lain. Dalam hal ini Anda cukup mengubah baris terakhir metode create_plugin_settings_page
menjadi berikut:
add_submenu_page( 'options-general.php', $page_title, $menu_title, $capability, $slug, $callback );
Di sini kita mengubah fungsi add_menu_page
menjadi add_submenu_page
dan menambahkan argumen baru. Argumen itu adalah item menu induk tempat halaman pengaturan baru akan berada di bawah. Dalam dokumentasi add_submenu_page
Anda dapat melihat daftar yang cukup bagus untuk item menu induk dan siputnya. Anda mungkin juga melihat bahwa kami tidak lagi memiliki dua argumen terakhir, $icon
dan $position
. Karena kita sekarang berada di bagian submenu, kita tidak lagi memiliki kendali atas posisi elemen. Juga, submenu tidak memiliki ikon yang tersedia untuk mereka sehingga tidak perlu untuk argumen itu.
Jika Anda menyimpan kode baru ini, Anda akan melihat bahwa halaman pengaturan kami akan ditampilkan di bawah item menu Pengaturan:

Dalam banyak kasus, tempat yang paling tepat untuk menambahkan halaman pengaturan plugin adalah di bawah item Pengaturan. Dalam codex WordPress dijelaskan bahwa bagian Pengaturan digunakan untuk “Menampilkan opsi plugin yang hanya boleh dilihat oleh administrator.” Namun, ini hanya pedoman, bukan aturan.
Sekarang setelah kita menyiapkan halaman pengaturan dan kita tahu cara memindahkan item, kita dapat mulai mengerjakan bidang. Pekerjaan yang telah kita lakukan sejauh ini akan digunakan kembali untuk berbagai metode di bawah ini.
Pendekatan 1: Menggunakan Fungsi WordPress Bawaan
Sebelum kita masuk terlalu jauh ke dalam kode, mari kita bahas beberapa pro dan kontra menggunakan pendekatan ini.
kelebihan
- Mudah diintegrasikan ke dalam halaman pengaturan yang ada
- Sanitasi dilakukan untuk Anda
- Tidak mungkin rusak karena kodenya dikelola oleh WordPress
- Dapat digunakan untuk tema dan plugin
- Fleksibel, aman, dan dapat diperluas
Kontra
- Validasi data khusus dilakukan secara manual
- Jenis bidang lanjutan (pengulang, peta, unggahan, dll.) lebih sulit untuk diterapkan
Kapan sebaiknya Anda menggunakan pendekatan ini?
Pendekatan ini cukup fleksibel sehingga dapat disesuaikan untuk halaman pengaturan yang sangat sederhana atau sangat canggih. Anda dapat menggunakan metode ini di sebagian besar situasi jika Anda tidak keberatan melakukan beberapa hal secara manual.
Mulai
Dengan menggunakan pendekatan ini kita harus mengikuti markup yang sama yang digunakan halaman opsi WordPress sendiri. Kita harus mengubah metode plugin_settings_page_content
menjadi berikut:
public function plugin_settings_page_content() { ?> <div class="wrap"> <h2>My Awesome Settings Page</h2> <form method="post" action="options.php"> <?php settings_fields( 'smashing_fields' ); do_settings_sections( 'smashing_fields' ); submit_button(); ?> </form> </div> <?php }
Markup di atas langsung dari codex WordPress untuk membuat halaman opsi. Nama metode harus cocok dengan nama panggilan balik yang kita masukkan ke dalam fungsi add_menu_page
di atas. div
pembungkus sebenarnya sama dengan formulir WordPress default dan akan menarik gaya dari bagian tersebut. Tag form
menunjuk ke penangan formulir opsi default untuk WordPress.
Tiga baris PHP melakukan beberapa hal:
- Fungsi
settings_fields
pada dasarnya adalah referensi untuk bidang kami lainnya. Argumen string yang Anda masukkan ke dalam fungsi itu harus cocok dengan variabel$slug
yang kita atur sebelumnya – itu akan ada di semua bidang yang kita daftarkan nanti di plugin. Fungsi ini juga menampilkan beberapa input tersembunyi untuk nonce, tindakan formulir, dan beberapa bidang lain untuk halaman opsi. - Fungsi berikutnya,
do_settings_sections
, adalah pengganti untuk bagian dan bidang yang akan kita daftarkan di tempat lain di plugin kita. - Fungsi terakhir,
submit_button
, akan menampilkan input submit, tetapi juga akan menambahkan beberapa kelas berdasarkan status halaman. Mungkin ada argumen lain yang ingin Anda sampaikan ke fungsisubmit_button
; mereka diuraikan dalam kodeks.
Jika kita me-refresh halaman pengaturan kita, kita akan mendapatkan sesuatu yang terlihat seperti ini:

Itu terlihat agak jarang! Mari kita mulai menyiapkan bidang sekarang.
Bagian dan Bidang
WordPress memisahkan halaman opsinya menjadi beberapa bagian. Setiap bagian dapat memiliki daftar bidang yang terkait dengannya. Kita perlu mendaftarkan bagian di plugin kita sebelum kita dapat mulai menambahkan bidang kita. Tambahkan kode berikut ke fungsi konstruktor Anda:
add_action( 'admin_init', array( $this, 'setup_sections' ) );
Kait ini akan mengatur bagian untuk halaman kita. Berikut adalah kode untuk panggilan balik:
public function setup_sections() { add_settings_section( 'our_first_section', 'My First Section Title', false, 'smashing_fields' ); }
Argumen pertama adalah pengidentifikasi unik untuk bagian dan kami akan menggunakan ini untuk bidang yang ingin kami tetapkan ke bagian. Pengidentifikasi ini harus unik untuk semua bagian baru di halaman ini. Argumen berikutnya adalah judul yang dihasilkan di atas bagian – Anda dapat membuatnya apa pun yang Anda inginkan. Argumen ketiga adalah panggilan balik. Saat ini saya mengaturnya ke false
, tetapi kami akan segera meninjaunya kembali. Argumen keempat adalah halaman opsi tempat opsi akan ditambahkan (variabel $slug
dari sebelumnya).
Jadi mengapa ada yang false
dalam panggilan balik kami? Nah, sesuatu yang tidak terlalu jelas saat menyiapkan opsi WordPress menggunakan dokumentasinya adalah beberapa bagian dapat berbagi panggilan balik. Seringkali saat Anda mengatur panggilan balik, ada hubungan 1-untuk-1 antara hook dan panggilan balik. Jadi sebagai contoh mari kita coba membuat tiga bagian dengan panggilan balik yang sama:
public function setup_sections() { add_settings_section( 'our_first_section', 'My First Section Title', array( $this, 'section_callback' ), 'smashing_fields' ); add_settings_section( 'our_second_section', 'My Second Section Title', array( $this, 'section_callback' ), 'smashing_fields' ); add_settings_section( 'our_third_section', 'My Third Section Title', array( $this, 'section_callback' ), 'smashing_fields' ); }
Ketiga bagian ini memiliki callback section_callback
yang disetel di slot argumen ketiga itu. Jika kita kemudian membuat metode yang cocok dengan panggilan balik itu dan meletakkan "Hello World" di sana:
public function section_callback( $arguments ) { echo '
Halo Dunia
'; }
kita mendapatkan sesuatu yang terlihat seperti ini:

Saya tahu apa yang Anda pikirkan, "Mengapa saya ingin memiliki teks yang sama di bawah semua bagian saya?" Jawabannya adalah Anda mungkin tidak akan melakukannya. Di sinilah kita bisa sedikit rumit dengan fungsi add_settings_section
. Jika Anda melihat dokumentasi untuk fungsi itu, Anda akan melihat bahwa di bagian Catatan halaman, fungsi panggilan balik akan diberi array argumen yang secara langsung berkorelasi dengan argumen di hook kita. Jika Anda masuk dan var_dump( $arguments )
Anda akan melihat semua argumen diteruskan ke fungsi kami.
Kami kemudian dapat menulis sakelar sederhana di panggilan balik kami untuk mengubah teks berdasarkan ID yang diteruskan ke dalamnya:
public function section_callback( $arguments ) { switch( $arguments['id'] ){ case 'our_first_section': echo 'This is the first description here!'; break; case 'our_second_section': echo 'This one is number two'; break; case 'our_third_section': echo 'Third time is the charm!'; break; } }
Sekarang kami memiliki teks khusus untuk setiap bagian yang dapat kami ubah dalam satu fungsi!

Tentu saja, Anda juga dapat menentukan panggilan balik unik untuk bagian ini, tetapi pendekatan ini memungkinkan Anda untuk menggabungkan kode ke dalam satu fungsi. Ide ini bekerja sama untuk menyiapkan bidang. Kita dapat meminta semua bidang kita berbagi panggilan balik dan membuatnya menghasilkan tipe bidang yang benar berdasarkan argumen yang kita berikan. Mari tambahkan bidang ke metode konstruktor kita. Letakkan kode ini tepat setelah bagian kita terhubung ke konstruktor:
add_action( 'admin_init', array( $this, 'setup_fields' ) );
Karena Anda sudah mengetahui latihannya, saya hanya akan memberi Anda panggilan balik untuk tindakan kami:
public function setup_fields() { add_settings_field( 'our_first_field', 'Field Name', array( $this, 'field_callback' ), 'smashing_fields', 'our_first_section' ); }
Argumen dalam fungsi ini mirip dengan argumen di fungsi bagian. Argumen pertama adalah pengidentifikasi unik untuk bidang tersebut. Yang kedua adalah label yang muncul di sebelah bidang. Dalam argumen ketiga Anda dapat melihat saya memanggil metode field_callback
; kami akan membuat panggilan balik itu hanya dalam satu detik. Yang keempat adalah halaman opsi yang ingin kita gunakan ( $slug
kita dari sebelumnya). Argumen kelima adalah pengidentifikasi unik untuk bagian yang ingin kita tetapkan bidang ini.
Berikut adalah kode untuk panggilan balik dalam argumen ketiga kami:
public function field_callback( $arguments ) { echo '<input name="our_first_field" type="text" value="' . get_option( 'our_first_field' ) . '" />'; }
Di sini saya hanya menyalin pengidentifikasi unik bidang ke dalam nama, ID, dan fungsi get_option
kami. Mari kita lihat bagaimana halaman kita terlihat dengan bidang baru kita terlampir:

Luar biasa, kami memiliki bidang kami di halaman! Coba tambahkan beberapa konten ke dalamnya dan tekan simpan perubahan, saya akan menunggu di sini…
Apakah kamu melakukan itu? Jika Anda telah melakukan semuanya dengan benar hingga saat ini, Anda seharusnya mendapatkan pesan kesalahan seperti ERROR: options page not found
, atau serupa. Alasan ini terjadi sebenarnya adalah fitur keamanan di WordPress.
Anda lihat, tanpa fitur ini, pengguna bisa masuk ke HTML dan mengubah nama bidang apa pun yang mereka inginkan, tekan simpan, dan itu akan memasukkan opsi itu ke dalam database dengan nama apa pun yang diberikan (dengan asumsi itu valid nama opsi). Ini dapat memungkinkan pengguna mana pun untuk mengubah opsi di halaman lain (bahkan yang biasanya tidak dapat mereka akses) hanya dengan memasukkan nama yang benar ke dalam bidang dan menekan simpan – tidak keren.
Masalah ini diselesaikan dengan menambahkan fungsi yang disebut register_setting
. Kecuali Anda secara khusus memberi tahu WordPress, "Hei, bidang ini diizinkan untuk disimpan di halaman ini", WordPress tidak akan memperbarui bidang dalam database. Jadi di bawah markup bidang kami, kami akan menambahkan fungsi baru ini. Berikut tampilan callback setelah kita menambahkan kode:
public function field_callback( $arguments ) { echo '<input name="our_first_field" type="text" value="' . get_option( 'our_first_field' ) . '" />'; register_setting( 'smashing_fields', 'our_first_field' ); }
Argumen pertama dalam fungsi baru adalah halaman opsi tempat kita ingin menyimpan bidang ( $slug
dari sebelumnya) dan argumen kedua adalah bidang yang ingin kita simpan. Sekarang coba dan perbarui bidang – itu berhasil!
Selamat! Anda baru saja menyimpan bidang pertama Anda menggunakan API Pengaturan WordPress. Sekarang bagaimana jika kita ingin memiliki beberapa jenis bidang yang berbeda, bukan hanya teks? Mari kita tinjau kembali panggilan balik bidang kita dan bicarakan tentang variabel $arguments
yang diteruskan ke fungsi kita.
Argumen Lapangan
Jika kita masuk ke bidang callback dan var_dump( $arguments )
kita akan mendapatkan array kosong. Apa yang memberi? Dalam panggilan balik bagian kami, kami mendapat banyak hal tentang bagian tersebut. Nah, ada sesuatu yang berbeda terjadi di sini. Jika Anda memeriksa dokumentasi untuk add_settings_field
, ada argumen kelima yang dapat diteruskan ke fungsi. Variabel itu secara langsung berkorelasi dengan variabel $arguments
dalam panggilan balik kami. Jadi kami akan ingin menempatkan barang-barang baru kami di sana.
Jika kita melihat salah satu bidang default di halaman pengaturan WordPress, kita dapat melihat ada beberapa area yang dapat kita tambahkan ke bidang kita untuk mendapatkan beberapa pemformatan default. Berikut adalah tangkapan layar bidang zona waktu di halaman pengaturan umum:

Menggunakan bidang ini sebagai titik awal, mari kita membahas data yang ingin kita berikan ke panggilan balik bidang kita.
- Pengidentifikasi unik
- Label untuk bidang (Zona waktu dalam contoh)
- Bagian mana yang harus masuk?
- Jenis bidang (teks, textarea, pilih, dll.)
- Jika ada beberapa opsi, kami akan menginginkannya
- Mungkin pengganti jika jenis bidang mendukungnya
- Teks pembantu (di sebelah kanan bidang dalam contoh)
- Teks tambahan (di bawah bidang dalam contoh)
- Mungkin pilihan default jika ada
Dari daftar ini kita dapat mengatur array asosiatif bidang dan nilai yang dapat kita berikan ke panggilan balik kita:
public function setup_fields() { $fields = array( array( 'uid' => 'our_first_field', 'label' => 'Awesome Date', 'section' => 'our_first_section', 'type' => 'text', 'options' => false, 'placeholder' => 'DD/MM/YYYY', 'helper' => 'Does this help?', 'supplemental' => 'I am underneath!', 'default' => '01/01/2015' ) ); foreach( $fields as $field ){ add_settings_field( $field['uid'], $field['label'], array( $this, 'field_callback' ), 'smashing_fields', $field['section'], $field ); register_setting( 'smashing_fields', $field['uid'] ); } }
Jadi hal pertama yang kita miliki di sini adalah variabel yang disebut $fields
yang akan menampung semua bidang yang ingin kita buat. Di dalam larik itu kami memiliki larik lain yang menyimpan data spesifik untuk setiap bidang. Saya telah menyiapkan data agar sama persis dengan daftar kami di atas. Kemudian, saya mengulang setiap bidang (kita akan menambahkan lebih lama) dalam array dan menambahkan bidang dan mendaftarkannya. Di akhir fungsi add_settings_field
saya juga menambahkan seluruh array data untuk bidang tertentu sehingga kami dapat melakukan beberapa hal dalam fungsi panggilan balik. Mari kita lihat fungsi panggilan balik itu di sini:
public function field_callback( $arguments ) { $value = get_option( $arguments['uid'] ); // Get the current value, if there is one if( ! $value ) { // If no value exists $value = $arguments['default']; // Set to our default } // Check which type of field we want switch( $arguments['type'] ){ case 'text': // If it is a text field printf( '<input name="%1$s" type="%2$s" placeholder="%3$s" value="%4$s" />', $arguments['uid'], $arguments['type'], $arguments['placeholder'], $value ); break; } // If there is help text if( $helper = $arguments['helper'] ){ printf( '<span class="helper"> %s</span>', $helper ); // Show it } // If there is supplemental text if( $supplimental = $arguments['supplemental'] ){ printf( '<p class="description">%s</p>', $supplimental ); // Show it } }
Dalam contoh di atas, kami melakukan beberapa hal. Kami menyetel nilai default untuk bidang jika kosong dan menambahkan teks pembantu dan tambahan. Namun, bagian terpenting dalam kode kita adalah pernyataan switch. Dalam pernyataan ini kita akan menguraikan bagaimana argumen kita akan ditangani berdasarkan jenis bidang yang kita inginkan.
Misalnya, jika kita memiliki bidang teks, kita tidak perlu memiliki banyak opsi. Namun, dropdown <select>
harus memiliki opsi agar berfungsi dengan baik. Karena kita sudah menyiapkan jenis teks, mari jalankan kode ini dan lihat apa yang kita dapatkan.

Saat Anda memuat halaman pengaturan plugin Anda, Anda akan melihat bidang teratas pada gambar ini. Bagian bawah adalah apa yang akan Anda lihat jika Anda menghapus konten dari bidang (yaitu placeholder). Jika saya menghapus argumen helper
atau tambahan dari supplimental
bidang kami, argumen tersebut akan hilang di halaman pengaturan. Kami juga dapat mengubah argumen section
dan berpindah-pindah penempatan bidang di bagian.

OK, jadi kami memiliki bidang teks; bagaimana dengan beberapa jenis bidang yang lebih kompleks? Mari kita lihat lagi pernyataan sakelar kami dan tambahkan opsi untuk area teks dan pilihan tunggal:
switch( $arguments['type'] ){ case 'text': // If it is a text field printf( '<input name="%1$s" type="%2$s" placeholder="%3$s" value="%4$s" />', $arguments['uid'], $arguments['type'], $arguments['placeholder'], $value ); break; case 'textarea': // If it is a textarea printf( '<textarea name="%1$s" placeholder="%2$s" rows="5" cols="50">%3$s</textarea>', $arguments['uid'], $arguments['placeholder'], $value ); break; case 'select': // If it is a select dropdown if( ! empty ( $arguments['options'] ) && is_array( $arguments['options'] ) ){ $options_markup = '; foreach( $arguments['options'] as $key => $label ){ $options_markup .= sprintf( '<option value="%s" %s>%s</option>', $key, selected( $value, $key, false ), $label ); } printf( '<select name="%1$s">%2$s</select>', $arguments['uid'], $options_markup ); } break; }
Dalam kode di atas Anda akan melihat beberapa perbedaan antara masing-masing jenis bidang. Meskipun area teks secara fungsional mirip dengan bidang teks biasa, mereka memerlukan markup yang berbeda. Pilih dropdown adalah hewan lain karena opsi. Kita perlu mengulang opsi dan menetapkan nilai, status yang dipilih, dan label. Jadi markup kami sangat berbeda.
Sekarang kita telah memperbarui fungsi panggilan balik kita, mari kita lihat bagaimana data bidang telah berubah:
$fields = array( array( 'uid' => 'our_first_field', 'label' => 'Awesome Date', 'section' => 'our_first_section', 'type' => 'text', 'options' => false, 'placeholder' => 'DD/MM/YYYY', 'helper' => 'Does this help?', 'supplemental' => 'I am underneath!', 'default' => '01/01/2015' ), array( 'uid' => 'our_second_field', 'label' => 'Awesome Date', 'section' => 'our_first_section', 'type' => 'textarea', 'options' => false, 'placeholder' => 'DD/MM/YYYY', 'helper' => 'Does this help?', 'supplemental' => 'I am underneath!', 'default' => '01/01/2015' ), array( 'uid' => 'our_third_field', 'label' => 'Awesome Select', 'section' => 'our_first_section', 'type' => 'select', 'options' => array( 'yes' => 'Yeppers', 'no' => 'No way dude!', 'maybe' => 'Meh, whatever.' ), 'placeholder' => 'Text goes here', 'helper' => 'Does this help?', 'supplemental' => 'I am underneath!', 'default' => 'maybe' ) );
Berikut adalah tiga bidang, masing-masing menggunakan jenis bidang yang berbeda di plugin kami. Yang pertama sudah kita lewati. Yang kedua adalah bidang textarea
baru kami. Kita dapat melewatkan parameter yang sama dengan array (dengan pengecualian UID), tetapi perubahan sederhana pada tipe kita dan kita akan mendapatkan textarea
sebagai gantinya. Bidang terakhir dalam array ini adalah dropdown pilih. Pembaruan utama di sini adalah penambahan array opsi. Kami menambahkan array asosiatif sederhana dengan kunci array sebagai nilai opsi HTML, dan labelnya. Dengan menggunakan array ini, inilah tampilan bidang kami:

Hampir selesai!
Kami sekarang memiliki halaman pengaturan plugin yang berfungsi. Kami telah menyiapkan bagian untuk halaman, opsi, semua panggilan balik, dan mendaftarkan bidang. Satu-satunya yang tersisa adalah mendapatkan nilai pengaturan kami di tempat lain. Percaya atau tidak, kami sudah melakukan ini. Di bagian atas panggilan balik bidang kami, Anda dapat melihat bahwa kami sedang memeriksa nilai basis data:
$value = get_option( $arguments['uid'] );
Kami dapat menggunakan kode yang sama di plugin (atau tema) kami dan cukup meneruskan uid
ke dalam fungsi. Jadi jika saya ingin mendapatkan nilai our_first_field
saya cukup menulis:
get_option('our_first_field')
Hei presto! Kami memiliki plugin kami yang luar biasa dan pengaturan kami yang luar biasa! Jelas kami hanya menyiapkan beberapa jenis bidang tetapi saya telah melalui dan menambahkan lebih banyak dalam repositori kode untuk pendekatan ini (khususnya bidang teks, kata sandi, angka, area teks, pilih dropdown, multiselects, tombol radio dan kotak centang).
Pendekatan 2: Menyiapkan Formulir dan Handler Kustom
Di masa lalu pendekatan ini adalah satu-satunya cara untuk menambahkan halaman pengaturan. Sebelum penulis plugin WordPress 2.7 harus membuat formulir dan penangan kustom mereka sendiri. Ini jelas menyebabkan banyak bug dan inkonsistensi antar plugin. Meskipun pendekatan ini agak usang, itu masih merupakan pilihan yang layak dalam beberapa kasus.
kelebihan
- Anda dapat mengirimkan formulir ke penangan khusus dan jarak jauh
- Anda dapat melewati beberapa batasan API Pengaturan bawaan
Kontra
- Kompatibilitas harus dijaga oleh pengembang
- Harus membersihkan dan memvalidasi secara manual
Kapan sebaiknya Anda menggunakan pendekatan ini?
Gunakan pendekatan ini ketika Anda benar-benar harus memiliki handler khusus atau antarmuka yang sangat khusus. Anda mungkin bisa lolos dengan Pendekatan 1 dalam banyak kasus, tetapi Anda memiliki lebih banyak fleksibilitas dengan validasi dan penanganan menggunakan metode ini.
Mulai
Sebelum kita masuk ke detailnya, kita perlu membuat skenario di mana kita akan menggunakan handler khusus. Demi kesederhanaan, mari kita buat formulir yang akan memverifikasi nama pengguna dan alamat email. Kita bisa menarik data dari database atau bahkan server jauh. Dalam hal ini saya akan menyiapkan array dengan nama pengguna dan alamat email yang valid untuk kami periksa. Kami kemudian akan menyimpan nilai bidang yang dimasukkan pengguna dan menyimpannya dalam database.
Membuat Formulir
Seperti yang saya sebutkan sebelumnya, kami akan mengikuti langkah yang sama seperti yang kami lakukan di "Membuat Halaman Plugin Dan Pengaturan Kami". Untuk pendekatan ini kami akan mengatur bidang kami menggunakan markup HTML statis. Kami akan menambahkan kode ini ke panggilan balik dari fungsi plugin_settings_page_content
seperti ini:
public function plugin_settings_page_content() { ?> <div class="wrap"> <h2>My Awesome Settings Page</h2> <form method="POST"> <table class="form-table"> <tbody> <tr> <th><label for="username">Username</label></th> <td><input name="username" type="text" value="" class="regular-text" /></td> </tr> <tr> <th><label for="email">Email Address</label></th> <td><input name="email" type="text" value="" class="regular-text" /></td> </tr> </tbody> </table> <p class="submit"> <input type="submit" name="submit" class="button button-primary" value="Check My Info!"> </p> </form> </div> <?php }
Anda dapat melihat di atas bahwa kami hanya menambahkan beberapa HTML statis untuk bidang kami. Kami menduplikasi markup dari halaman pengaturan inti WordPress. Kami juga menghilangkan tindakan formulir sehingga akan mengirimkan formulir ke halaman saat ini sebagai lawan dari default options.php handler.
Sebelum kita menulis handler kustom kita, mari kita masukkan beberapa fitur keamanan cepat. Hal pertama yang harus kita lakukan adalah meletakkan nonce di formulir kita. Nonces akan melindungi dari upaya pemalsuan permintaan lintas situs, yang mirip dengan spoofing pengguna atau serangan replay. Mari kita letakkan nonce di HTML kita:
<form method="POST"> <?php wp_nonce_field( 'awesome_update', 'awesome_form' ); ?> <table class="form-table">
wp_nonce_field
akan menambahkan beberapa bidang tersembunyi ke formulir kita; nonce dan perujuk. Kami akan kembali ke nonce ketika kami melewati kode handler.
Selanjutnya kita perlu menambahkan bidang untuk mendeteksi ketika formulir telah diperbarui. Kita dapat melakukan ini hanya dengan menambahkan bidang tersembunyi di bagian atas formulir kita:
<form method="POST"> <input type="hidden" name="updated" value="true" /> <?php wp_nonce_field( 'awesome_update', 'awesome_form' ); ?> <table class="form-table">
Sekarang kami dapat menempatkan potongan kode di bagian atas halaman kami untuk mendeteksi kapan formulir kami dikirimkan dan mengirimkan kami ke penangan khusus kami:
public function plugin_settings_page_content() { if( $_POST['updated'] === 'true' ){ $this->handle_form(); } ?> <div class="wrap"> <h2>My Awesome Settings Page</h2>
Di sini kami hanya memeriksa apakah bidang updated
tersembunyi telah dikirimkan dan, jika sudah, kami memanggil metode di plugin kami yang disebut handle_form
. Di sinilah kita bisa mulai menulis handler kustom kita.
Membuat penangan
Ada beberapa hal yang perlu kita periksa di handler sebelum kita benar-benar mengelola data formulir. Pertama-tama kita perlu memeriksa apakah nonce kita ada dan valid:
public function handle_form() { if( ! isset( $_POST['awesome_form'] ) || ! wp_verify_nonce( $_POST['awesome_form'], 'awesome_update' ) ){ ?> <div class="error"> <p>Sorry, your nonce was not correct. Please try again.</p> </div> <?php exit; } else { // Handle our form data } }
Kode di atas memverifikasi bahwa nonce benar. Jika tidak valid, kami memberikan pesan kepada pengguna tentang mengapa formulir tidak diperbarui. Jika nonce ada dan benar, kami dapat menangani formulir kami. Mari kita tulis kode untuk form handler kita sekarang (kode ini akan menggantikan komentar pada cuplikan di atas):
$valid_usernames = array( 'admin', 'matthew' ); $valid_emails = array( '[email protected]', '[email protected]' ); $username = sanitize_text_field( $_POST['username'] ); $email = sanitize_email( $_POST['email'] ); if( in_array( $username, $valid_usernames ) && in_array( $email, $valid_emails ) ){ update_option( 'awesome_username', $username ); update_option( 'awesome_email', $email );?> <div class="updated"> <p>Your fields were saved!</p> </div> <?php } else { ?> <div class="error"> <p>Your username or email were invalid.</p> </div> <?php }
Mari kita lihat kode di bagian ini. Beberapa baris pertama adalah larik nama pengguna/email valid yang akan kita periksa. Nilai array ini dapat diisi dari mana saja.
Dua baris berikutnya adalah nilai yang dimasukkan pengguna kami ke dalam formulir. Kami menggunakan fungsi sanitasi bawaan yang diberikan WordPress kepada kami. Langkah ini penting untuk menghindari beberapa kerentanan dengan formulir web. Selanjutnya, kami memeriksa apakah nilai yang diberikan oleh pengguna berada dalam array nilai yang dapat diterima. Jika ya, perbarui opsi formulir di database. Langkah ini juga bisa diganti dengan mekanisme penyimpanan khusus. Kami juga memberikan pesan kepada pengguna bahwa bidang mereka telah disimpan. Jika input pengguna tidak valid, kami memberi tahu mereka.
Hal terakhir yang perlu kita lakukan adalah menunjukkan field yang disimpan dalam form setelah dimasukkan. Kami akan melakukannya dengan cara yang sama seperti kami mengambil bidang ini di tempat lain di plugin: dengan fungsi get_option
. Berikut adalah bidang setelah kami menambahkan kode yang benar:
<tr> <th><label for="username">Username</label></th> <td><input name="username" type="text" value="<?php echo get_option('awesome_username'); ?>" class="regular-text" /></td> </tr> <tr> <th><label for="email">Email Address</label></th> <td><input name="email" type="text" value="<?php echo get_option('awesome_email'); ?>" class="regular-text" /></td> </tr>
Sekarang kami siap untuk menguji formulir kami. Coba masukkan nama pengguna admin dan alamat email [email protected] . Anda harus mendapatkan yang berikut di formulir Anda:

Jika Anda mencoba menyetel salah satu bidang ke nilai yang tidak valid, Anda akan mendapatkan pesan kesalahan dan bidang tersebut tidak boleh diperbarui karena penangan khusus kami.
Itu saja untuk pendekatan kedua kami! Anda sekarang telah menyiapkan formulir dan penangan khusus untuk mengelola bidang plugin Anda. Kode lengkap untuk pendekatan ini dapat ditemukan di repositori artikel ini. Sekarang, mari kita beralih ke pendekatan terakhir kita.
Pendekatan 3: Mengintegrasikan ACF (Bidang Kustom Lanjutan) Ke dalam Plugin Anda
Jika Anda belum pernah menggunakan ACF oleh Elliot Condon, izinkan saya memperkenalkan Anda. ACF adalah manajer lapangan yang luar biasa untuk WordPress. Salah satu hal terbaik tentang itu adalah antarmuka konfigurasi bidang. Itu membuatnya cukup mudah untuk memutar bidang untuk sejumlah halaman berbeda di dalam WordPress (seperti posting, halaman, pengguna, taksonomi, bahkan halaman opsi terintegrasi mereka sendiri). Anda mungkin berpikir “Saya tidak dapat mengintegrasikan plugin orang lain ke dalam plugin saya sendiri – itu teduh!” tetapi Mr. Condon memahami keadaan buruk rekan-rekan pengembangnya dan telah merencanakan hal ini dalam pluginnya. Anda dapat melihat dokumentasinya tentang topik ini, tetapi saya akan menyatakan kembali sebagiannya di sini. Mari kita pergi ke aturan.
- Pertama, jika Anda mendistribusikan plugin gratis, Anda harus menggunakan ACF versi gratis. Ini agar orang tidak bisa mendapatkan versi PRO dari plugin gratis Anda – itu tidak keren. Anda dapat menggunakan versi PRO di plugin dan tema premium tanpa masalah, pastikan Anda membeli lisensi pengembang.
- Kedua, jangan mengubah info hak cipta ACF. Beri pria itu pujian!
- Terakhir, jangan mendistribusikan kunci lisensi dengan plugin Anda.
Sekarang, pro dan kontra dari pendekatan ini:
kelebihan
- Sangat mudah untuk diintegrasikan ke dalam tema dan plugin
- Anda dapat memanfaatkan bidang lanjutan yang merupakan bagian dari ACF
- Pembaruan kode dan keamanan dikelola oleh tim ACF
- ACF memiliki tambahan dan dukungan yang bagus jika Anda buntu
- Mengonfigurasi bidang Anda sangat sederhana karena UI konfigurasi bidang
Kontra
- Akses terbatas ke markup
- Membuat ketergantungan untuk plugin atau tema Anda
- Agar ACF tetap terkini, Anda harus tetap memperbaruinya di file plugin/tema Anda (info lebih lanjut di bawah)
Kapan sebaiknya Anda menggunakan pendekatan ini?
Saat Anda ingin membangun antarmuka pengaturan lanjutan dengan sangat cepat dan Anda tidak perlu menyesuaikan tampilan dan nuansa.
Mulai
For this approach I will show you how to set up the options page for the free version of ACF. To view a guide on setting up the PRO version check out the ACF documentation. To get started we will be adding ACF to our plugin directory. First, download the latest version of ACF and unzip its contents. In your plugin directory create a (Lihat versi besar)
Again, we will follow the steps we did in “Creating Our Plugin And Settings Page”. Before we get into that, though, we should include ACF in our plugin.
Include ACF In Your Plugin
It's actually pretty easy to include ACF in your plugin – there are only three steps. First we have to include the main ACF file with PHP. Add the following code to the bottom of our constructor function:
include_once( plugin_dir_path( __FILE__ ) . 'vendor/advanced-custom-fields/acf.php' );
If you refresh the admin you should see a new menu item titled Custom Fields . Before we go into that page and start setting up our fields we need to update a couple of paths in ACF. We need to tell ACF to look for its front-end assets and file includes in our plugin directory instead of its normal place. Add these two hooks to your constructor:
add_filter( 'acf/settings/path', array( $this, 'update_acf_settings_path' ) ); add_filter( 'acf/settings/dir', array( $this, 'update_acf_settings_dir' ) );
And the callbacks for those hooks:
public function update_acf_settings_path( $path ) { $path = plugin_dir_path( __FILE__ ) . 'vendor/advanced-custom-fields/'; return $path; } public function update_acf_settings_dir( $dir ) { $dir = plugin_dir_url( __FILE__ ) . 'vendor/advanced-custom-fields/'; return $dir; }
The first callback updates the include paths for the PHP files within the ACF plugin. The second updates the URIs for the ACF assets. Now we can set up our fields.
Configuring Your Fields
Now comes the fun part: the ACF field configuration UI. Add a title and any fields you'd like in your form. There is a great walkthrough of what everything on this page does in the ACF documentation. Here's how I have set up mine:

Once you are ready hit the Publish button on the right and your fields will be saved. Now we have to get the fields we set up into our plugin. Right now they only exist in the database. On the left-hand navigation, click the Tools item. On the new page, select the field group we just created and hit Generate Export Code . This will create a chunk of PHP code that we can now include in our plugin.
To add the options, we need to add a method call to our constructor. Add this line to the end of your constructor after our ACF include:
$this->setup_options();
Then we can create the method that will wrap our options:
public function setup_options() { if( function_exists( 'register_field_group' ) ) { register_field_group(array ( 'id' => 'acf_awesome-options', 'title' => 'Awesome Options', 'fields' => array ( array ( 'key' => 'field_562dc35316a0f', 'label' => 'Awesome Name', 'name' => 'awesome_name', 'type' => 'text', 'default_value' => ', 'placeholder' => ', 'prepend' => ', 'append' => ', 'formatting' => 'html', 'maxlength' => ', ), array ( 'key' => 'field_562dc9affedd6', 'label' => 'Awesome Date', 'name' => 'awesome_date', 'type' => 'date_picker', 'date_format' => 'yymmdd', 'display_format' => 'dd/mm/yy', 'first_day' => 1, ), array ( 'key' => 'field_562dc9bffedd7', 'label' => 'Awesome WYSIWYG', 'name' => 'awesome_wysiwyg', 'type' => 'wysiwyg', 'default_value' => ', 'toolbar' => 'full', 'media_upload' => 'yes', ), ), 'location' => array ( array ( array ( 'param' => 'options_page', 'operator' => '==', 'value' => 'smashing_fields', ), ), ), 'menu_order' => 0, 'position' => 'normal', 'style' => 'default', 'label_placement' => 'top', 'instruction_placement' => 'label', 'hide_on_screen' => ', 'active' => 1, 'description' => ', )); } }
Now that we have our fields ready to go, we can add them to the settings page.
Modifying The Settings Page Code
To add the fields we just created to the page we will need to update our plugin_settings_page_content
method.
Previously, we set up the form tag for our page. In this case we will let ACF do that part for us. Here is what our updated function should look like:
public function plugin_settings_page_content() { do_action('acf/input/admin_head'); // Add ACF admin head hooks do_action('acf/input/admin_enqueue_scripts'); // Add ACF scripts $options = array( 'id' => 'acf-form', 'post_id' => 'options', 'new_post' => false, 'field_groups' => array( 'acf_awesome-options' ), 'return' => admin_url('admin.php?page=smashing_fields'), 'submit_value' => 'Update', ); acf_form( $options ); }
Dua baris pertama dari fungsi kita menambahkan skrip dan gaya yang kita perlukan untuk bidang pengaturan. Setelah itu kami mengonfigurasi opsi untuk formulir kami. Anda mungkin memperhatikan bahwa nilai dalam argumen field_groups
cocok dengan ID dari fungsi register_field_group
kami. Untuk melihat parameter konfigurasi lainnya, lihat dokumentasi acf_form
. Baris terakhir dalam fungsi kita sebenarnya akan merender formulir.
Jika Anda mencoba memuat halaman pengaturan sekarang, Anda mungkin melihat bahwa halaman tersebut sebenarnya rusak. Ini karena ACF perlu melokalkan beberapa variabel untuk JavaScript. Untuk melakukan ini, kita perlu menambahkan kait lain ke konstruktor kita:
add_action( 'admin_init', array( $this, 'add_acf_variables' ) );
Sekarang kita perlu mengatur panggilan balik:
public function add_acf_variables() { acf_form_head(); }
Anda dapat mencoba menambahkan beberapa konten dan menyimpannya dan itu akan berfungsi seperti dua pendekatan kami yang lain. Seperti inilah tampilan halaman kita:

Hanya ada beberapa item pembersihan yang perlu kami tangani:
Anda mungkin ingin menyembunyikan fakta bahwa Anda menggunakan ACF untuk plugin Anda. Jika demikian, Anda perlu menyembunyikan item menu Bidang Kustom . Anda dapat melakukan ini dengan menambahkan cuplikan ini ke fungsi konstruktor Anda:
add_filter( 'acf/settings/show_admin', '__return_false' );
Kita harus menghapus versi database dari grup bidang kita. Cukup buka bagian bidang khusus dan tekan tombol tempat sampah. Langkah ini opsional karena hanya akan memengaruhi lingkungan tempat Anda membuat plugin, tetapi dapat menimbulkan masalah jika Anda menguji plugin di lingkungan yang sama.
Menggunakan Bidang ACF Dalam Plugin Anda
Untuk mendapatkan bidang ACF yang Anda buat, Anda hanya perlu menggunakan fungsi get_field
ACF default. Opsi pertama harus berupa ID unik untuk bidang dan argumen kedua disetel ke 'option'
. Inilah cara kami mendapatkan bidang Tanggal Luar Biasa :
get_field( 'awesome_date', 'option' )
Dan itu saja. Anda sekarang telah menyiapkan plugin dengan pengaturan ACF! Anda dapat melihat kode untuk pendekatan ini di repositori.
Kesimpulan
Jadi begitulah: tiga cara untuk membuat plugin Anda dapat dikonfigurasi. Saya akan senang mendengar tentang plugin yang dapat Anda buat menggunakan metode ini. Sekali lagi, saya telah menyiapkan repositori yang menampung kode untuk masing-masing pendekatan ini. Jangan ragu untuk memotongnya dan menyesuaikannya agar sesuai dengan kebutuhan Anda sendiri.
Adapun preferensi pribadi saya untuk pendekatan ini, saya cenderung condong ke Pendekatan 1. Saya lebih memilih untuk menjaga ketergantungan sesedikit mungkin dalam plugin saya dan Anda dapat menyesuaikan markup untuk tema halaman pengaturan untuk proyek kustom. Untuk prototipe cepat, atau proyek di mana saya perlu menyiapkan bidang yang sangat canggih, saya akan menggunakan ACF – tetapi ini menambah tingkat kerumitan dalam mengelola pembaruan plugin.
Perlu juga disebutkan proposal untuk Fields API oleh Scott Clark. Meskipun saat ini masih dalam proses, API pada dasarnya akan memungkinkan pengembang plugin dan tema untuk menggunakan antarmuka yang sama dengan Customizer API untuk membuat bidang pengaturan di area lain dari panel admin.
Alternatif ACF
Seperti yang ditunjukkan dalam komentar di bawah, dan untuk memberi pengembang opsi lain yang mirip dengan pendekatan ACF, Anda dapat melihat beberapa alternatif yang mungkin menawarkan fitur berbeda. Jika Anda memiliki lebih banyak, silakan kirimkan di komentar di bawah! Di sini mereka tanpa urutan tertentu:
- CMB2 oleh WebDevStudios
- Meta Box oleh Tran Ngoc Tuan Anh ( Rilwis )