WordPress Eklentinize Yapılandırılabilir Alanlar Eklemek İçin 3 Yaklaşım

Yayınlanan: 2022-03-10
Kısa özet ↬ Bir WordPress eklentisi oluşturan herkes, eklentinin nasıl çalıştığını değiştirmek için yapılandırılabilir alanlar oluşturma ihtiyacını anlar. Bir eklentide yapılandırılabilir seçenekler için sayısız kullanım ve söz konusu seçenekleri uygulamak için neredeyse birçok yol vardır. Görüyorsunuz, WordPress eklenti yazarlarının ayar sayfalarında kendi işaretlemelerini oluşturmalarına izin veriyor. Bir yan etki olarak, ayar sayfaları eklentiler arasında büyük farklılıklar gösterebilir. Bu yazıda, eklentinizi yapılandırılabilir hale getirebileceğiniz üç yaygın yoldan bahsedeceğiz. Bir ayarlar sayfası oluşturarak başlayacağız ve varsayılan WordPress Ayarları API'sini kullanarak alanlarımızı oluşturacağız. Ardından, alanlarınızı özel bir işleyiciyle nasıl kuracağınız konusunda size yol göstereceğim. Son olarak, harika bir yapılandırılabilir alan eklentisi Advanced Custom Fields'ı (ACF) kendi eklentinize nasıl entegre edeceğinizi göstereceğim.

Bir WordPress eklentisi oluşturan herkes, eklentinin nasıl çalıştığını değiştirmek için yapılandırılabilir alanlar oluşturma ihtiyacını anlar. Bir eklentide yapılandırılabilir seçenekler için sayısız kullanım ve söz konusu seçenekleri uygulamak için neredeyse birçok yol vardır. Görüyorsunuz, WordPress eklenti yazarlarının ayar sayfalarında kendi işaretlemelerini oluşturmalarına izin veriyor. Bir yan etki olarak, ayar sayfaları eklentiler arasında büyük farklılıklar gösterebilir.

Bu yazıda, eklentinizi yapılandırılabilir hale getirebileceğiniz üç yaygın yoldan bahsedeceğiz. Bir ayarlar sayfası oluşturarak başlayacağız ve varsayılan WordPress Ayarları API'sini kullanarak alanlarımızı oluşturacağız.

SmashingMag'de Daha Fazla Okuma :

  • WordPress'i Özel Alanlarla Genişletin
  • WordPress İçin Özel Alan Hackleri
  • Gelişmiş Özel Alanları Kendi Kontrollerinizle Genişletme
  • Özel Gönderi Türleri İçin Eksiksiz Kılavuz

Ardından, alanlarınızı özel bir işleyiciyle nasıl kuracağınız konusunda size yol göstereceğim. Son olarak, harika bir yapılandırılabilir alan eklentisi Advanced Custom Fields'ı (ACF) kendi eklentinize nasıl entegre edeceğinizi göstereceğim.

Atlamadan sonra daha fazlası! Aşağıdan okumaya devam edin ↓

Bu uzun bir gönderi olduğundan, ana bölümlerin her birine bağlantılar içeren bir içindekiler tablosu:

  • Eklenti ve Ayarlar Sayfamızı Oluşturma
  • Yaklaşım 1: Yerleşik WordPress İşlevselliğini Kullanma
  • Yaklaşım 2: Özel Form ve İşleyici Ayarlama
  • Yaklaşım 3: ACF'yi (Gelişmiş Özel Alanlar) Eklentinize Entegre Etme

Kod örnekleri için lütfen bu gönderiye eşlik edecek şekilde kurduğum depoya bakın.

Eklenti ve Ayarlar Sayfamızı Oluşturma

Yapmamız gereken ilk şey eklentimizi kurmak ve bir ayarlar sayfası oluşturmak. Bu makalede özetlenen üç yaklaşımın tümü, aşağıdaki eklenti yapısıyla başlar. Bu eklenti yapısı nesne yönelimli olduğundan, eklentiniz prosedürel olarak yazılmışsa kendi kodunuzda birkaç farklılık olabilir. Eylemlerde ve filtrelerde geri arama işlevi biçimine özellikle dikkat edin.

 /* 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();

Sınıfımızın içine, ayarlar sayfasını eklemek için bir eylem kancası ekleyeceğiz:

 public function __construct() { // Hook into the admin menu add_action( 'admin_menu', array( $this, 'create_plugin_settings_page' ) ); }

Eylemimizin geri create_plugin_settings_page olduğunu görebilirsiniz, o halde bu yöntemi oluşturalım. Not: Kodumuza bir bağlam vermek için bağımsız değişkenleri ayrı adlandırılmış değişkenler olarak ayarladım, ancak bellekten tasarruf etmek için değerleri doğrudan işleve yerleştirebilirsiniz.

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

Daha fazla bilgi için add_menu_page için WP kodeksine bakın.

Bu fonksiyon, menü öğesinin yanı sıra sayfamızı da oluşturacaktır. Buradaki önemli kısımlar, bilgi, yetenek ve geri arama argümanlarıdır. Daha sonra alanlarımızı kaydetmek için kullanacağımız sümüklü böcek, bu yüzden onu bir yere yazın. Ayarlar sayfanıza farklı kullanıcı düzeylerinin erişmesine izin verme özelliğini değiştirebilirsiniz. Geri çağırmaya gelince, kısa süre içinde bu yöntemi oluşturacağız. Menünün simgesini değiştirmek için doğrudan işleve bir dashicon sınıfı da koyabileceğinize dikkat edin. Son argüman, menü öğesinin menü içindeki konumudur; Menüde ayarlarınızın düşmesini istediğiniz yeri bulmak için bu numarayla oynayın. Not: Diğer menü öğeleriyle çakışmaları önlemek için ondalık değerleri kullanabilirsiniz.

Bir sonraki adımımız, ayarlar sayfamız için plugin_settings_page_content geri arama yöntemini oluşturmaktır.

 public function plugin_settings_page_content() { echo 'Hello World!'; }

Eklentinizi kaydeder ve WordPress yönetici panelini yenilerseniz aşağıdakileri görmelisiniz:

Ayarlar sayfası için başlangıç ​​düzeni
Ayarlar sayfasının başlangıç ​​durumu. (Büyük versiyonu görüntüle)

Ayarlar sayfanızın üst düzey bir menü öğesi olduğunu görebilirsiniz. Ayarlar sayfanızın ihtiyaçlarına göre bu şekilde bırakmayı tercih edebilirsiniz. Ancak eklenti ayarlarınızı başka bir menü öğesi altında da bulundurmak isteyebilirsiniz. Bu durumda, create_plugin_settings_page yönteminin son satırını aşağıdaki gibi değiştirmeniz yeterlidir:

 add_submenu_page( 'options-general.php', $page_title, $menu_title, $capability, $slug, $callback );

Burada add_submenu_page işlevini add_menu_page olarak değiştiriyoruz ve yeni bir argüman hazırlıyoruz. Bu argüman, yeni ayarlar sayfasının altında olacağı üst menü öğesidir. add_submenu_page belgelerinde, ana menü öğeleri ve bunların sümüklü böcekleri için oldukça iyi bir liste görebilirsiniz. Ayrıca artık son iki argümanımız olmadığını da görebilirsiniz, $icon ve $position . Artık alt menü bölümünde olduğumuz için artık elemanın konumu üzerinde kontrolümüz yok. Ayrıca, alt menülerin kendilerine uygun simgeleri yoktur, bu nedenle bu argümana gerek yoktur.

Bu yeni kodu kaydederseniz, Ayarlar menü öğesinin altında ayarlar sayfamızın görüntülendiğini göreceksiniz:

Alt menü sayfası artık ayarlar altında
Ayarlar sayfası artık Ayarlar menüsü altına yerleştirilmiştir. (Büyük versiyonu görüntüle)

Çoğu durumda, eklenti ayarları sayfası eklemek için en uygun yer Ayarlar öğesinin altındadır. WordPress kodeksinde, Ayarlar bölümünün "Yalnızca yöneticilerin görüntülemesi gereken eklenti seçeneklerini görüntülemek" için kullanıldığını açıklar. Ancak, bu sadece bir kılavuzdur, bir kural değil.

Artık ayarlar sayfamızı oluşturduğumuza ve öğeleri nasıl hareket ettireceğimizi bildiğimize göre, tarlalar üzerinde çalışmaya başlayabiliriz. Şimdiye kadar yaptığımız çalışmalar aşağıdaki çeşitli yöntemler için yeniden kullanılacaktır.

Yaklaşım 1: Yerleşik WordPress İşlevselliğini Kullanma

Kodun derinliklerine inmeden önce, bu yaklaşımı kullanmanın bazı artılarını ve eksilerini gözden geçirelim.

Artıları

  • Mevcut ayar sayfalarına entegre edilmesi kolay
  • Dezenfekte sizin için yapılır
  • Kod WordPress tarafından yönetildiğinden kırılması olası değildir
  • Hem temalar hem de eklentiler için kullanılabilir
  • Esnek, güvenli ve genişletilebilir

Eksileri

  • Özel veri doğrulama manueldir
  • Gelişmiş alan türlerinin (tekrarlayıcılar, haritalar, yüklemeler vb.) uygulanması daha zordur

Bu yaklaşımı ne zaman kullanmalısınız?

Bu yaklaşım, çok basit veya çok gelişmiş ayar sayfaları için özelleştirilebilecek kadar esnektir. Bazı şeyleri manuel olarak yapmaktan çekinmiyorsanız, çoğu durumda bu yöntemi kullanabilirsiniz.

Başlarken

Bu yaklaşımı kullanarak, WordPress'in kendi seçenekler sayfalarının kullandığı aynı işaretlemeyi izlememiz gerekecek. plugin_settings_page_content yöntemimizi aşağıdaki şekilde değiştirmeliyiz:

 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 }

Yukarıdaki işaretleme, doğrudan seçenekler sayfalarının oluşturulmasıyla ilgili WordPress kodeksinden alınmıştır. Yöntem adı, yukarıdaki add_menu_page işlevine koyduğumuz geri çağırma adıyla eşleşmelidir. Sarmalayıcı div , aslında varsayılan bir WordPress formuyla aynıdır ve stilleri bu bölümlerden çeker. form etiketi, WordPress için varsayılan seçenekler form işleyicisine işaret ediyor.

PHP'nin üç satırı birkaç şey yapar:

  • settings_fields işlevi temel olarak alanlarımızın geri kalanı için bir referanstır. Bu işleve koyduğunuz dize argümanı, daha önce ayarladığımız $slug değişkeniyle eşleşmelidir - daha sonra eklentide kaydettiğimiz tüm alanlarda olacaktır. Bu işlev aynı zamanda nonce, form eylemi ve seçenekler sayfası için birkaç diğer alan için birkaç gizli girdi verir.
  • Sonraki işlev, do_settings_sections , eklentimizde başka bir yere kaydedeceğimiz bölümler ve alanlar için bir yer tutucudur.
  • Son işlev olan submit_button , gönderim girdisini çıkaracak, ancak sayfanın durumuna göre bazı sınıflar da ekleyecektir. submit_button işlevine iletmek isteyeceğiniz başka argümanlar olabilir; bunlar kodekste özetlenmiştir.

Ayarlar sayfamızı yenilersek, şuna benzeyen bir şey almalıyız:

Boş WordPress Ayarları Sayfası
Bölümleri ve alanları kaydetmeden önce ayarlar sayfamız.

Biraz seyrek görünüyor! Şimdi alanları kurmaya başlayalım.

Bölümler ve Alanlar

WordPress, seçenekler sayfalarını bölümlere ayırır. Her bölüm, kendisiyle ilişkili alanların bir listesine sahip olabilir. Alanlarımızı eklemeye başlamadan önce eklentimizde bir bölüm kaydetmemiz gerekiyor. Yapıcı işlevinize aşağıdaki kodu ekleyin:

 add_action( 'admin_init', array( $this, 'setup_sections' ) );

Bu kanca sayfamız için bölümleri ayarlayacaktır. İşte geri arama için kod:

 public function setup_sections() { add_settings_section( 'our_first_section', 'My First Section Title', false, 'smashing_fields' ); }

İlk argüman bölüm için benzersiz bir tanımlayıcıdır ve bunu bölüme atamak istediğimiz alanlar için kullanacağız. Bu tanımlayıcılar, bu sayfadaki tüm yeni bölümler için benzersiz olmalıdır. Bir sonraki argüman, bölümün üzerinde oluşturulan başlıktır – istediğiniz herhangi bir şeyi yapabilirsiniz. Üçüncü argüman geri aramadır. Şu anda false olarak ayarladım, ancak bunu kısa süre içinde tekrar gözden geçireceğiz. Dördüncü argüman, seçeneklerin ekleneceği seçenekler sayfasıdır (önceki $slug değişkeni).

Peki neden geri aramamızda false var? WordPress seçeneklerini kendi belgelerini kullanarak ayarlarken çok net olmayan bir şey, birden çok bölümün bir geri aramayı paylaşabilmesidir. Genellikle bir geri arama kurduğunuzda, kanca ile geri arama arasında 1'e 1 ilişki vardır. Yani sadece bir örnek olarak aynı geri arama ile üç bölüm oluşturmayı deneyelim:

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

Bu bölümlerin üçü de bu üçüncü bağımsız değişken yuvasında ayarlanmış geri arama section_callback sahiptir. Daha sonra bu geri aramayla eşleşen bir yöntem oluşturur ve oraya bir "Merhaba Dünya" bırakırsak:

 public function section_callback( $arguments ) { echo '

Selam Dünya

'; }

şuna benzeyen bir şey elde ederiz:

Aynı geri arama işlevini paylaşan üç bölüm
Aynı geri aramayı paylaşan üç bölüm.

Ne düşündüğünüzü biliyorum, "Neden tüm bölümlerimin altında aynı metni görmek isteyeyim ki?" Cevap, muhtemelen yapmazsınız. Burası, add_settings_section işleviyle biraz uğraşabileceğimiz yer. Bu işlevin belgelerine bakarsanız, sayfanın Notlar bölümünde geri çağırma işlevine kancamızdaki argümanlarla doğrudan ilişkili bir dizi argüman atanacağını göreceksiniz. İçeri girip var_dump( $arguments ) yaparsanız, tüm argümanların fonksiyonumuza aktarıldığını göreceksiniz.

Daha sonra, kendisine iletilen kimliğe göre metni değiştirmek için geri aramamıza basit bir anahtar yazabiliriz:

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

Artık her bölüm için tek bir işlevde değiştirebileceğimiz özel metnimiz var!

Her bölümün altında özel metin
Her bölümün altında özel metin.

Elbette, bu bölümler için benzersiz geri aramalar da belirleyebilirsiniz, ancak bu yaklaşım, kodunuzu tek bir işlevde birleştirmenize olanak tanır. Bu fikir, alanları ayarlamak için aynı şekilde çalışır. Tüm alanlarımızın bir geri aramayı paylaşmasını ve ilettiğimiz argümanlara dayalı olarak doğru alan tipini vermesini sağlayabiliriz. Alanları yapıcı yöntemimize ekleyelim. Bu kodu, yapıcıya bölümlerimizin kancasından hemen sonra koyun:

 add_action( 'admin_init', array( $this, 'setup_fields' ) );

Tatbikatı zaten bildiğiniz için, eylemimiz için size geri arama yapacağım:

 public function setup_fields() { add_settings_field( 'our_first_field', 'Field Name', array( $this, 'field_callback' ), 'smashing_fields', 'our_first_section' ); }

Bu işlevdeki argümanlar, bölümler işlevindekilere benzer. İlk argüman, alan için benzersiz tanımlayıcıdır. İkincisi, alanın yanında görünen etikettir. Üçüncü argümanda, field_callback yöntemini çağırdığımı görebilirsiniz; bu geri aramayı bir saniye içinde oluşturacağız. Dördüncüsü, kullanmak istediğimiz seçenekler sayfasıdır (önceki $slug ). Beşinci argüman, bu alanı atamak istediğimiz bölümün benzersiz tanımlayıcısıdır .

Üçüncü argümanımızdaki geri aramanın kodu:

 public function field_callback( $arguments ) { echo '<input name="our_first_field" type="text" value="' . get_option( 'our_first_field' ) . '" />'; }

Burada sadece alanın benzersiz tanımlayıcısını isme, kimliğe ve get_option . Yeni alanımız eklendiğinde sayfamızın nasıl göründüğüne bakalım:

İlk alanımızla birlikte ayarlar sayfamız.
İlk alanımızın eklendiği ayar sayfası.

Harika, sayfada alanımız var! Buna biraz içerik eklemeyi ve değişiklikleri kaydetmeyi deneyin, burada bekleyeceğim…

Yaptın mı? Bu noktaya kadar her şeyi yaptıysanız, ERROR: options page not found veya benzeri gibi bir şey söyleyerek bir hata almış olmalısınız. Bunun olmasının nedeni aslında WordPress'teki bir güvenlik özelliğidir.

Görüyorsunuz, bu özellik olmadan, bir kullanıcı HTML'ye girebilir ve bir alanın adını istediği herhangi bir şeyle değiştirebilir, kaydet'e basabilir ve bu seçeneği, verilen adla (geçerli olduğunu varsayarak) veritabanına girecektir. seçenek adı). Bu, herhangi bir kullanıcının diğer sayfalardaki seçenekleri (normalde erişemedikleri bile olsa) alana yalnızca doğru adı girerek ve kaydet düğmesine basarak değiştirmesine izin verebilir.

Bu sorun, register_setting adlı bir işlev eklenerek çözülür. WordPress'e özellikle "Hey, bu alanın bu sayfada kaydedilmesine izin verilir" demedikçe, WordPress veritabanındaki bir alanı güncellemeyecektir. Yani alan işaretlememizin altına bu yeni işlevi ekleyeceğiz. Kodu ekledikten sonra geri arama şöyle görünür:

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

Yeni fonksiyondaki ilk argüman, alanı kaydetmek istediğimiz seçenekler sayfasıdır (önceki $slug ) ve ikinci argüman kaydetmek istediğimiz alandır. Şimdi alanı güncellemeye çalışın - işe yaradı!

Tebrikler! Az önce WordPress Ayarları API'sini kullanarak ilk alanınızı kaydettiniz. Şimdi, sadece metin yerine bazı farklı alan türlerine sahip olmak istiyorsak ne olur? Alan geri çağrımızı tekrar ziyaret edelim ve fonksiyonumuza geçen $arguments değişkeni hakkında konuşalım.

Alan Argümanları

Geri arama ve var_dump( $arguments ) alanımıza girersek boş bir dizi elde ederiz. Ne oluyor? Geri arama bölümümüzde bölümle ilgili bir sürü şey var. Pekala, burada farklı bir şey oluyor. add_settings_field belgelerine göz atarsanız, işleve iletilebilecek beşinci bir argüman vardır. Bu değişken, geri aramamızdaki $arguments değişkeniyle doğrudan ilişkilidir. Bu yüzden yeni eşyalarımızı oraya koymak isteyeceğiz.

Bir WordPress ayarları sayfasındaki varsayılan alanlardan birine bakarsak, varsayılan biçimlendirme elde etmek için alanımıza ekleyebileceğimiz birkaç alan olduğunu görebiliriz. İşte genel ayarlar sayfasındaki saat dilimi alanının ekran görüntüsü:

WordPress saat dilimi alanı
WordPress saat dilimi alanı. (Büyük versiyonu görüntüle)

Bu alanı başlangıç ​​noktası olarak kullanarak, alan geri aramamıza iletmek istediğimiz verilerin üzerinden geçelim.

  • benzersiz tanımlayıcı
  • Alanın etiketi (örnekte Saat dilimi)
  • hangi bölüme girmeli
  • Alanın türü (metin, metin alanı, seçim vb.)
  • Birden fazla seçenek olması durumunda, bunları isteyeceğiz
  • Alan türü destekliyorsa yer tutucu olabilir
  • Yardımcı metin (örnekteki alanın sağında)
  • Ek metin (örnekteki alanın altında)
  • Varsa varsayılan bir seçim olabilir

Bu listeden, geri aramamıza aktarabileceğimiz ilişkisel bir alan ve değer dizisi oluşturabiliriz:

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

Yani burada sahip olduğumuz ilk şey, yaratmak istediğimiz tüm alanları tutacak $fields adlı bir değişkendir. Bu dizinin içinde, her alan için belirli verileri tutan başka bir dizimiz var. Verileri yukarıdaki listemizle tam olarak eşleşecek şekilde ayarladım. Daha sonra dizideki her bir alan arasında (birazdan ekleyeceğiz) döngüye giriyorum ve alanı ekliyorum ve kaydediyorum. add_settings_field işlevinin sonunda, geri çağırma işlevinde bazı şeyler yapabilmemiz için o belirli alan için tüm veri dizisini de ekliyorum. Buradaki geri çağırma işlevine bir göz atalım:

 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 } }

Yukarıdaki örnekte, birkaç şey yapıyoruz. Boşsa alanlar için varsayılan değerleri ayarlıyor ve yardımcı ve ek metni ekliyoruz. Ancak kodumuzun en önemli kısmı switch ifadesidir. Bu açıklamada, istediğimiz alan türüne göre argümanlarımızın nasıl ele alınacağını ana hatlarıyla belirteceğiz.

Örneğin, bir metin alanımız varsa, birden fazla seçeneğe ihtiyacımız yok. Ancak, bir <select> açılır listesinin düzgün çalışması için seçeneklere sahip olması gerekir. Önceden ayarlanmış metin türlerimiz olduğundan, bu kodu çalıştıralım ve ne elde edeceğimizi görelim.

Yer tutucu da dahil olmak üzere alanımız dolduruldu
Alanımız, yer tutucu metin de dahil olmak üzere doldurulmuştur. (Büyük versiyonu görüntüle)

Eklenti ayarları sayfanızı yüklediğinizde, bu resimde en üstteki alanı görmelisiniz. Alt kısım, içeriği alandan (yani yer tutucudan) kaldırırsanız göreceğiniz şeydir. Alanlar supplimental helper veya tamamlayıcı argümanları kaldıracak olsaydım, ayarlar sayfasında kaybolmaları gerekirdi. Ayrıca section argümanını değiştirebilir ve alanın bölümlerdeki yerleşiminde hareket edebiliriz.

Tamam, metin alanlarımız var; biraz daha karmaşık alan türlerine ne dersiniz? Switch ifademize bir kez daha bakalım ve metin alanları ve tekli seçimler için seçeneği ekleyelim:

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

Yukarıdaki kodda, alan türlerinin her biri arasında birkaç fark göreceksiniz. Metin alanları, normal metin alanlarına işlevsel olarak benzer olsa da, farklı biçimlendirme gerektirirler. Seçili açılır menüler, seçenekler nedeniyle tamamen başka bir hayvandır. Seçenekler arasında dolaşmamız ve değerleri, seçili durumları ve etiketleri ayarlamamız gerekiyor. Yani işaretlememiz büyük ölçüde farklı.

Artık geri çağırma fonksiyonumuzu güncelledik, şimdi saha verilerinin nasıl değiştiğine bakalım:

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

Eklentimizde her biri farklı bir alan türü kullanan üç alan. İlkini çoktan geçtik. İkincisi yeni textarea alanımız. Aynı parametreleri diziyle (UID hariç) iletebiliriz, ancak türümüzde basit bir değişiklik yapın ve bunun yerine bir textarea alacağız. Bu dizideki son alan, seçim açılır menüsüdür. Buradaki ana güncelleme, seçenekler dizisinin eklenmesidir. HTML seçenek değeri olarak dizi anahtarı ve etiket ile basit bir ilişkisel dizi ekliyoruz. Bu diziyi kullanarak alanlarımız şöyle görünür:

Alanlar doldurulduktan sonra ayarlar sayfamız
Alanları olan ayarlar sayfamız. (Büyük versiyonu görüntüle)

Neredeyse bitti!

Artık işleyen bir eklenti ayarları sayfamız var. Sayfanın bölümlerini, seçenekleri, tüm geri aramaları ayarladık ve alanları kaydettik. Geriye kalan tek şey ayar değerlerimizi başka bir yerden almak. İster inanın ister inanmayın, bunu zaten yaptık. Alan geri aramamızın en üstünde, veritabanı değerini kontrol ettiğimizi görebilirsiniz:

 $value = get_option( $arguments['uid'] );

Aynı kodu eklentimizde (veya uid ) kullanabilir ve kullanıcı kimliğini işleve geçirebiliriz. Eğer our_first_field değerini almak isteseydim, basitçe şunu yazardım:

 get_option('our_first_field')

Hey! Çabuk! Harika eklentimiz ve harika ayarlarımız var! Açıkçası sadece birkaç alan türü ayarladık, ancak bu yaklaşım için kod deposuna daha fazlasını ekledim ve ekledim (özellikle metin alanları, parolalar, sayılar, metin alanları, açılır listeler, çoklu seçimler, radyo düğmeleri ve onay kutuları).

Yaklaşım 2: Özel Bir Form ve İşleyici Ayarlama

Geçmişte bu yaklaşım, ayar sayfaları eklemenin tek yoluydu. WordPress 2.7 eklentisinden önce yazarların kendi özel formlarını ve işleyicilerini oluşturmaları gerekiyordu. Bu açıkçası eklentiler arasında birçok hataya ve tutarsızlığa yol açtı. Bu yaklaşım biraz kullanımdan kaldırılmış olsa da, bazı durumlarda hala geçerli bir seçenektir.

Artıları

  • Formu özel ve uzak işleyicilere gönderebilirsiniz
  • Yerleşik Ayarlar API kısıtlamalarından bazılarını atlayabilirsiniz

Eksileri

  • Uyumluluk geliştirici tarafından sağlanmalıdır
  • El ile sterilize edilmeli ve doğrulanmalıdır

Bu yaklaşımı ne zaman kullanmalısınız?

Kesinlikle özel bir işleyiciye veya son derece özel bir arayüze sahip olmanız gerektiğinde bu yaklaşımı kullanın. Çoğu durumda Yaklaşım 1'den muhtemelen kurtulabilirsiniz, ancak bu yöntemi kullanarak doğrulama ve işleme konusunda daha fazla esnekliğe sahipsiniz.

Başlarken

Ayrıntılara girmeden önce, özel bir işleyici kullanacağımız bir senaryo bulmamız gerekiyor. Basitlik adına, bir kullanıcı adını ve bir e-posta adresini doğrulayacak bir form yapalım. Verileri bir veritabanından veya hatta uzak bir sunucudan çekebiliriz . Bu durumda, kontrol etmemiz için geçerli kullanıcı adları ve e-posta adresleri olan bir dizi oluşturacağım. Daha sonra kullanıcının girdiği alan değerlerini saklayacağız ve bunları veritabanında saklayacağız.

Form Oluşturma

Daha önce de bahsettiğim gibi, “Eklenti ve Ayarlar Sayfamızı Oluşturma” bölümünde yaptığımız adımların aynısını izleyeceğiz. Bu yaklaşım için alanlarımızı statik HTML işaretlemesi kullanarak ayarlayacağız. Bu kodu plugin_settings_page_content işlevinden gelen geri aramaya şu şekilde ekleyeceğiz:

 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 }

Yukarıda, alanlarımız için sadece bazı statik HTML eklediğimizi görebilirsiniz. İşaretlemeyi temel WordPress ayar sayfalarından kopyalıyoruz. Ayrıca, varsayılan options.php işleyicisinin aksine formu mevcut sayfaya göndermesi için form eylemini de atlıyoruz.

Özel işleyicimizi yazmadan önce, bazı hızlı güvenlik özelliklerini koyalım. Yapmamız gereken ilk şey, formumuza bir nonce koymak. Nonces, kullanıcı sızdırma veya yeniden oynatma saldırılarına benzer şekilde, siteler arası istek sahteciliği girişimlerine karşı koruma sağlar. Nonce'yi HTML'mize koyalım:

 <form method="POST"> <?php wp_nonce_field( 'awesome_update', 'awesome_form' ); ?> <table class="form-table">

wp_nonce_field , formumuza birkaç gizli alan ekleyecektir; nonce ve yönlendiren. İşleyici kodunu incelediğimizde nonce'ye geri döneceğiz.

Ardından, formun ne zaman güncellendiğini tespit etmek için bir alan eklememiz gerekiyor. Bunu, formumuzun en üstüne gizli bir alan ekleyerek yapabiliriz:

 <form method="POST"> <input type="hidden" name="updated" value="true" /> <?php wp_nonce_field( 'awesome_update', 'awesome_form' ); ?> <table class="form-table">

Artık formumuzun ne zaman gönderildiğini algılamak ve bizi özel işleyicimize göndermek için sayfamızın üst kısmına bir kod parçacığı koyabiliriz:

 public function plugin_settings_page_content() { if( $_POST['updated'] === 'true' ){ $this->handle_form(); } ?> <div class="wrap"> <h2>My Awesome Settings Page</h2>

Burada sadece gizli updated alanın gönderilip gönderilmediğini kontrol ediyoruz ve varsa, eklentimizde handle_form adlı bir yöntemi çağırıyoruz. Özel işleyicimizi yazmaya buradan başlayabiliriz.

İşleyiciyi oluşturma

Form verilerini gerçekten yönetmeden önce işleyicide kontrol etmemiz gereken birkaç şey var. İlk önce nonce'mizin var olup olmadığını ve geçerli olup olmadığını kontrol etmemiz gerekiyor:

 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 } }

Yukarıdaki kod, nonce'nin doğru olduğunu doğrular. Geçersiz ise, kullanıcıya formun neden güncellenmediğine dair bir mesaj veriyoruz. Nonce varsa ve doğruysa, formumuzu ele alabiliriz. Şimdi form işleyicimizin kodunu yazalım (bu kod yukarıdaki pasajdaki yorumun yerini alacak):

 $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 }

Bu bölümdeki kodu inceleyelim. İlk birkaç satır, kontrol edeceğimiz geçerli kullanıcı adları/e-posta dizileridir. Bu dizi değerleri herhangi bir yerden doldurulabilir.

Sonraki iki satır kullanıcımızın forma girdiği değerlerdir. WordPress'in bize sağladığı yerleşik temizleme işlevlerini kullanıyoruz. Bu adım, web formlarıyla ilgili çeşitli güvenlik açıklarından kaçınmak için önemlidir. Ardından, kullanıcılar tarafından sağlanan değerlerin kabul edilebilir değerler dizimizde olup olmadığını kontrol ediyoruz. Varsa, veritabanındaki form seçeneklerini güncelleyin. Bu adım, özel bir depolama mekanizmasıyla da değiştirilebilir. Ayrıca kullanıcıya alanlarının kaydedildiğine dair bir mesaj veriyoruz. Kullanıcının girişi geçersizse, bunu onlara söyleriz.

Yapmamız gereken son şey, formda saklanan alanları girdikten sonra göstermek. Bunu, eklentinin başka bir yerinde bu alanları alacağımız şekilde yapacağız: get_option işleviyle. Doğru kodu ekledikten sonraki alanlar şunlardır:

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

Artık formumuzu test etmeye hazırız. admin kullanıcı adını ve [email protected] e-posta adresini girmeyi deneyin. Formunuzda aşağıdakileri almalısınız:

Doğru değerleri girdikten sonra kaydedilen alanlar
Doğru değerleri girdikten sonra kaydedilen alanlar. (Büyük versiyonu görüntüle)

Herhangi bir alanı geçersiz bir değere ayarlamayı denerseniz, bir hata mesajı almalısınız ve özel işleyicimiz nedeniyle alanlar güncellenmemelidir.

İkinci yaklaşımımız bu kadar! Artık eklenti alanlarınızı yönetmek için özel bir form ve işleyici ayarladınız. Bu yaklaşım için tamamlanmış kod bu makalenin deposunda bulunabilir. Şimdi son yaklaşımımıza geçelim.

Yaklaşım 3: ACF'yi (Gelişmiş Özel Alanlar) Eklentinize Entegre Etme

Henüz ACF by Elliot Condon kullanmadıysanız, sizi tanıştırayım. ACF, WordPress için harika bir alan yöneticisidir. Bununla ilgili en iyi şeylerden biri alan yapılandırma arayüzüdür. WordPress içindeki bir dizi farklı sayfa için alanları döndürmeyi oldukça kolaylaştırır (yazılar, sayfalar, kullanıcılar, taksonomiler, hatta kendi entegre seçenekler sayfaları gibi). “Başkasının eklentisini kendi eklentime entegre edemem – bu çok karanlık!” diye düşünebilirsiniz. ancak Bay Condon, diğer geliştiricilerin kötü durumunu anlıyor ve eklentisinde bunu planladı. Bu konuyla ilgili belgelerini görüntüleyebilirsiniz, ancak bazılarını burada yeniden yazacağım. Hadi kuralları gözden geçirelim.

  1. İlk olarak, ücretsiz bir eklenti dağıtıyorsanız, ACF'nin ücretsiz sürümünü kullanmanız gerekir . Bu, insanların ücretsiz eklentinizden PRO sürümünü alamamaları içindir – bu hiç hoş olmaz. PRO sürümünü premium eklentilerde ve temalarda sorunsuz kullanabilirsiniz, geliştirici lisansını satın aldığınızdan emin olun.
  2. İkincisi, ACF'nin telif hakkı bilgisini değiştirmeyin. Adama biraz kredi ver!
  3. Son olarak, lisans anahtarını eklentinizle birlikte dağıtmayın.

Şimdi, bu yaklaşımın artıları ve eksileri:

Artıları

  • Temalara ve eklentilere entegrasyonu çok kolay
  • ACF'nin parçası olan gelişmiş alanlardan yararlanabilirsiniz.
  • Kod ve güvenlik güncellemeleri ACF ekibi tarafından yönetilir
  • ACF, takılırsanız harika eklentilere ve desteğe sahiptir
  • Alan yapılandırma arayüzü sayesinde alanlarınızı yapılandırmak son derece basittir

Eksileri

  • İşaretlemeye sınırlı erişim
  • Eklentiniz veya temanız için bir bağımlılık oluşturur
  • ACF'yi güncel tutmak için eklenti/tema dosyalarınızda güncel tutmalısınız (daha fazla bilgi aşağıdadır)

Bu yaklaşımı ne zaman kullanmalısınız?

Çok hızlı bir şekilde gelişmiş ayarlar arayüzü oluşturmak istediğinizde ve görünümü ve hissi özelleştirmeniz gerekmez.

Başlarken

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 (Büyük versiyonu görüntüle)

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:

ACF fields configured
My ACF fields in the configuration UI. (Büyük versiyonu görüntüle)

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

Fonksiyonumuzun ilk iki satırı, ayar alanları için ihtiyaç duyacağımız scriptleri ve stilleri ekliyor. Bundan sonra formumuz için seçenekleri yapılandırıyoruz. field_groups bağımsız değişkenindeki değerin, register_field_group işlevimizdeki kimlikle eşleştiğini fark edebilirsiniz. Diğer yapılandırma parametrelerini görmek için acf_form belgelerine bakın. Fonksiyonumuzdaki son satır aslında formu oluşturacak.

Ayarlar sayfasını şimdi yüklemeye çalışırsanız, sayfanın gerçekten bozuk olduğunu görebilirsiniz. Bunun nedeni, ACF'nin JavaScript için birkaç değişkeni yerelleştirmesi gerekmesidir. Bunu yapmak için yapıcımıza başka bir kanca eklememiz gerekiyor:

 add_action( 'admin_init', array( $this, 'add_acf_variables' ) );

Şimdi geri aramayı ayarlamamız gerekiyor:

 public function add_acf_variables() { acf_form_head(); }

Biraz içerik eklemeyi ve kaydetmeyi deneyebilirsiniz ve bu, diğer iki yaklaşımımız gibi çalışmalıdır. Sayfamız şöyle görünmelidir:

Tamamlanmış ACF formu
Tamamlanmış ACF formumuz. (Büyük versiyonu görüntüle)

Adresine ihtiyacımız olan sadece birkaç temizlik maddesi var:

  • Eklentiniz için ACF kullandığınız gerçeğini gizlemek isteyebilirsiniz. Bu durumda, Özel Alanlar menü öğesini gizlemeniz gerekir. Bunu, bu parçacığı yapıcı işlevinize ekleyerek yapabilirsiniz:

     add_filter( 'acf/settings/show_admin', '__return_false' );
  • Alan grubumuzun veritabanı versiyonunu kaldırmalıyız. Özel alanlar bölümüne gidin ve çöp düğmesine basın. Bu adım, yalnızca eklentiyi oluşturduğunuz ortamı etkileyeceğinden isteğe bağlıdır, ancak eklentinizi aynı ortamda test ediyorsanız sorunlara neden olabilir.

Eklentinizde ACF Alanlarını Kullanma

Oluşturduğunuz ACF alanlarını almak için varsayılan ACF get_field işlevini kullanmanız yeterlidir. İlk seçenek, alanın benzersiz kimliği ve ikinci argüman 'option' olarak ayarlanmalıdır. Müthiş Tarih alanını şu şekilde elde ederiz:

 get_field( 'awesome_date', 'option' )

Ve bu kadar. Artık ACF ayarlarına sahip bir eklenti kurdunuz! Bu yaklaşımın kodunu depoda görüntüleyebilirsiniz.

Çözüm

İşte karşınızda: Eklentilerinizi yapılandırılabilir hale getirmenin üç yolu. Bu yöntemleri kullanarak oluşturabileceğiniz eklentileri duymayı çok isterim. Bir kez daha, bu yaklaşımların her birinin kodunu barındıran bir havuz kurdum. Lütfen onları çatallamaktan ve kendi ihtiyaçlarınıza göre özelleştirmekten çekinmeyin.

Bu yaklaşımlar için kişisel tercihlerime gelince, Yaklaşım 1'e eğilimliyim. Eklentilerimde mümkün olduğunca az bağımlılık tutmayı tercih ediyorum ve özel projeler için ayarlar sayfasını temaya göre biçimlendirmeyi özelleştirebilirsiniz. Hızlı prototipler veya çok gelişmiş alanlar kurmam gereken projeler için ACF kullanacağım - ancak bu, eklenti güncellemelerini yönetmeye bir miktar karmaşıklık katıyor.

Ayrıca Scott Clark'ın Fields API önerisinden de bahsetmeye değer. Şu anda hala devam eden bir çalışma olsa da, API esas olarak eklenti ve tema geliştiricilerine, yönetici panelinin diğer alanlarında ayar alanları oluşturmak için Özelleştirici API ile aynı arayüzü kullanma becerisine izin verecektir.

ACF Alternatifleri

Aşağıdaki yorumlarda belirtildiği gibi ve geliştiricilere ACF yaklaşımına benzer başka seçenekler sunmak için farklı özellikler sunabilecek bazı alternatiflere göz atabilirsiniz. Daha fazlasına sahipseniz, lütfen bunları aşağıdaki yorumlarda gönderin! Burada belirli bir sırada değiller:

  • WebDevStudios tarafından CMB2
  • Meta Box, Tran Ngoc Tuan Anh (Rilwis)