3 abordări pentru adăugarea câmpurilor configurabile la pluginul dvs. WordPress

Publicat: 2022-03-10
Rezumat rapid ↬ Oricine a creat un plugin WordPress înțelege necesitatea de a crea câmpuri configurabile pentru a modifica modul în care funcționează pluginul. Există nenumărate utilizări pentru opțiunile configurabile într-un plugin și aproape tot atâtea modalități de implementare a respectivelor opțiuni. Vedeți, WordPress permite autorilor de plugin-uri să-și creeze propriul marcaj în paginile lor de setări. Ca efect secundar, paginile de setări pot varia foarte mult între pluginuri. În acest articol, vom analiza trei moduri comune prin care vă puteți configura pluginul. Vom începe prin a crea o pagină de setări și vom crea câmpurile folosind API-ul implicit de setări WordPress. Apoi vă voi explica cum să vă configurați câmpurile cu un handler personalizat. În cele din urmă, vă voi arăta cum să integrați un plugin grozav de câmpuri configurabile Câmpuri personalizate avansate (ACF) în propriul dvs. plugin.

Oricine a creat un plugin WordPress înțelege necesitatea de a crea câmpuri configurabile pentru a modifica modul în care funcționează pluginul. Există nenumărate utilizări pentru opțiunile configurabile într-un plugin și aproape tot atâtea modalități de implementare a respectivelor opțiuni. Vedeți, WordPress permite autorilor de plugin-uri să-și creeze propriul marcaj în paginile lor de setări. Ca efect secundar, paginile de setări pot varia foarte mult între pluginuri.

În acest articol, vom analiza trei moduri comune prin care vă puteți configura pluginul. Vom începe prin a crea o pagină de setări și vom crea câmpurile folosind API-ul implicit de setări WordPress.

Citiți suplimentare despre SmashingMag:

  • Extindeți WordPress cu câmpuri personalizate
  • Trucuri de câmpuri personalizate pentru WordPress
  • Extinderea câmpurilor personalizate avansate cu propriile controale
  • Ghidul complet pentru tipurile de postări personalizate

Apoi vă voi explica cum să vă configurați câmpurile cu un handler personalizat. În cele din urmă, vă voi arăta cum să integrați un plugin grozav de câmpuri configurabile Câmpuri personalizate avansate (ACF) în propriul dvs. plugin.

Mai multe după săritură! Continuați să citiți mai jos ↓

Deoarece aceasta este o postare lungă, iată un cuprins cu link-uri către fiecare dintre secțiunile majore:

  • Crearea paginii noastre de plugin și setări
  • Abordarea 1: Utilizarea funcționalității WordPress încorporate
  • Abordarea 2: Configurarea unui formular personalizat și a unui handler
  • Abordarea 3: Integrarea ACF (Câmpuri personalizate avansate) în pluginul dvs

Pentru exemple de cod, vă rugăm să consultați depozitul pe care l-am creat pentru a însoți această postare.

Crearea paginii noastre de plugin și setări

Primul lucru pe care trebuie să-l facem este să ne setăm pluginul și să creăm o pagină de setări. Toate cele trei abordări prezentate în acest articol încep cu structura pluginului de mai jos. Această structură de plugin este orientată pe obiecte, așa că pot exista câteva diferențe în propriul cod dacă pluginul este scris procedural. Acordați o atenție deosebită formatului funcției de apel invers în acțiuni și filtre.

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

În cadrul clasei noastre vom adăuga un cârlig de acțiune pentru a adăuga pagina de setări:

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

Puteți vedea că apelul invers al acțiunii noastre este create_plugin_settings_page , așa că haideți să creăm acea metodă. Notă: am configurat argumentele ca variabile numite separate pentru a oferi un anumit context codului nostru, dar pur și simplu puteți plasa valorile direct în funcție pentru a economisi memorie.

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

Aruncă o privire la codexul WP pentru add_menu_page pentru mai multe informații.

Această funcție va crea pagina noastră, precum și elementul de meniu. Părțile importante aici sunt argumentele slug, capacitate și callback. Limacul pe care îl vom folosi mai târziu pentru a ne înregistra câmpurile, așa că scrieți-l undeva. Puteți modifica capacitatea de a permite accesul la diferite niveluri de utilizator la pagina dvs. de setări. În ceea ce privește apelul invers, vom crea acea metodă în curând. Observați că puteți pune și o clasă dashicon direct în funcție pentru a schimba pictograma pentru meniu. Ultimul argument este poziția elementului de meniu în meniu; jucați-vă cu acest număr pentru a găsi locul din meniu în care doriți să cadă setările. Notă: puteți utiliza valori zecimale pentru a evita conflictele cu alte elemente de meniu.

Următorul nostru pas este să creăm metoda de apel invers plugin_settings_page_content pentru pagina noastră de setări.

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

Dacă salvați pluginul și reîmprospătați panoul de administrare WordPress, ar trebui să vedeți următoarele:

Se începe aspectul pentru pagina de setări
Starea de pornire a paginii de setări. (Vezi versiunea mare)

Puteți vedea că pagina dvs. de setări este un element de meniu de nivel superior. Este posibil să preferați să o lăsați astfel, în funcție de nevoile paginii dvs. de setări. Cu toate acestea, poate doriți să aveți setările pluginului dvs. sub alt element de meniu. În acest caz, veți schimba pur și simplu ultima linie a metodei create_plugin_settings_page în următoarea:

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

Aici schimbăm funcția add_menu_page în add_submenu_page și predăm un nou argument. Acest argument este elementul de meniu părinte în care se va afla noua pagină de setări. În documentația add_submenu_page puteți vedea o listă destul de bună pentru articolele din meniul părinte și slug-urile acestora. De asemenea, puteți vedea că nu mai avem ultimele două argumente, $icon și $position . Din moment ce ne aflăm acum în secțiunea submeniului, nu mai avem control asupra poziției elementului. De asemenea, submeniurile nu au pictograme disponibile, așa că nu este nevoie de acest argument.

Dacă salvați acest cod nou, veți vedea că pagina noastră de setări va fi afișată sub elementul de meniu Setări:

Pagina submeniului este acum în setări
Pagina de setări a fost acum plasată în meniul Setări. (Vezi versiunea mare)

În multe cazuri, cel mai potrivit loc pentru a adăuga o pagină de setări pentru plugin este sub elementul Setări. În codexul WordPress, se explică că secțiunea Setări este folosită pentru „Afișează opțiunile de plugin pe care numai administratorii ar trebui să le vadă”. Cu toate acestea, aceasta este doar un ghid, nu o regulă.

Acum că avem pagina de setări configurată și știm cum să mutăm elementele, putem începe să lucrăm la câmpuri. Munca pe care am făcut-o până acum va fi reutilizată pentru diferitele metode de mai jos.

Abordarea 1: Utilizarea funcționalității WordPress încorporate

Înainte de a pătrunde prea mult în cod, să trecem peste câteva dintre avantajele și dezavantajele utilizării acestei abordări.

Pro

  • Ușor de integrat în paginile de setări existente
  • Igienizarea se face pentru tine
  • Este puțin probabil să se rupă, deoarece codul este gestionat de WordPress
  • Poate fi folosit atât pentru teme, cât și pentru pluginuri
  • Flexibil, sigur și extensibil

Contra

  • Validarea datelor personalizate este manuală
  • Tipurile de câmp avansate (repetoare, hărți, încărcări etc.) sunt mai dificil de implementat

Când ar trebui să utilizați această abordare?

Această abordare este suficient de flexibilă încât poate fi personalizată pentru pagini de setări foarte simple sau foarte avansate. Puteți folosi această metodă în majoritatea situațiilor dacă nu vă deranjează să faceți unele lucruri manual.

Noțiuni de bază

Folosind această abordare, va trebui să urmăm același marcaj pe care îl folosesc paginile de opțiuni proprii ale WordPress. Ar trebui să ne modificăm metoda plugin_settings_page_content după cum urmează:

 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 }

Marcajul de mai sus este direct din codexul WordPress pentru crearea paginilor de opțiuni. Numele metodei ar trebui să se potrivească cu numele de apel invers pe care l-am pus în funcția add_menu_page de mai sus. Wrapper-ul div este de fapt același cu un formular WordPress implicit și va extrage stilurile din acele secțiuni. Eticheta de form indică opțiunile implicite de gestionare a formularelor pentru WordPress.

Cele trei linii PHP fac mai multe lucruri:

  • Funcția settings_fields este practic o referință pentru restul câmpurilor noastre. Argumentul șir pe care îl puneți în acea funcție ar trebui să se potrivească cu variabila $slug pe care am configurat-o mai devreme – va fi în toate câmpurile pe care le înregistrăm mai târziu în plugin. Această funcție scoate, de asemenea, câteva intrări ascunse pentru nonce, acțiune de formular și alte câteva câmpuri pentru pagina de opțiuni.
  • Următoarea funcție, do_settings_sections , este un substituent pentru secțiunile și câmpurile pe care le vom înregistra în altă parte în pluginul nostru.
  • Ultima funcție, submit_button , va afișa intrarea de trimitere, dar va adăuga și câteva clase în funcție de starea paginii. Pot exista și alte argumente pe care veți dori să le transmiteți în funcția submit_button ; sunt conturate în codex.

Dacă ne reîmprospătăm pagina de setări, ar trebui să obținem ceva care arată astfel:

Pagina de setări WordPress goală
Pagina noastră de setări înainte de înregistrarea secțiunilor și câmpurilor.

Arată puțin rar! Să începem configurarea câmpurilor acum.

Secțiuni și câmpuri

WordPress își separă paginile de opțiuni în secțiuni. Fiecare secțiune poate avea o listă de câmpuri asociate. Trebuie să înregistrăm o secțiune în pluginul nostru înainte de a începe să ne adăugăm câmpurile. Adăugați următorul cod la funcția dvs. de constructor:

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

Acest cârlig va configura secțiunile pentru pagina noastră. Iată codul pentru apel invers:

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

Primul argument este un identificator unic pentru secțiune și îl vom folosi pentru câmpurile pe care dorim să le atribuim secțiunii. Acești identificatori ar trebui să fie unici pentru toate secțiunile noi de pe această pagină. Următorul argument este titlul care este generat deasupra secțiunii – îl puteți face orice doriți. Al treilea argument este apelul invers. Momentan l-am setat la false , dar o vom revizui în curând. Al patrulea argument este pagina de opțiuni la care vor fi adăugate opțiunile (variabila $slug de mai devreme).

Deci, de ce există un false în apelul nostru invers? Ei bine, ceva care nu este foarte clar atunci când configurați opțiunile WordPress folosind documentația lor este că mai multe secțiuni pot partaja un apel invers. Adesea, atunci când configurați un apel invers, există o relație de 1 pentru 1 între cârlig și apel invers. Deci, doar pentru un exemplu, să încercăm să creăm trei secțiuni cu același apel invers:

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

Toate aceste trei secțiuni au setarea callback section_callback în acel al treilea slot de argument. Dacă apoi creăm o metodă care se potrivește cu acea revenire și lansăm un „Hello World” acolo:

 public function section_callback( $arguments ) { echo '

Salut Lume

'; }

obținem ceva care arată așa:

Trei secțiuni care au aceeași funcție de apel invers
Trei secțiuni care partajează același apel invers.

Știu la ce te gândești: „De ce naiba aș vrea să am același text în toate secțiunile mele?” Răspunsul este că probabil că nu ai face-o. Aici putem deveni puțin complicati cu funcția add_settings_section . Dacă te uiți la documentația pentru acea funcție, vei vedea că în porțiunea Note a paginii funcției de apel invers i se va atribui o serie de argumente care se corelează direct cu argumentele din hook-ul nostru. Dacă intrați și var_dump( $arguments ) veți vedea toate argumentele trecând în funcția noastră.

Putem apoi să scriem o comutare simplă în apelul nostru pentru a schimba textul pe baza ID-ului care este transmis în el:

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

Acum avem text personalizat pentru fiecare secțiune pe care îl putem schimba într-o singură funcție!

Text personalizat sub fiecare secțiune
Text personalizat sub fiecare secțiune.

Desigur, puteți specifica apeluri inverse unice și pentru aceste secțiuni, dar această abordare vă permite să vă consolidați codul într-o singură funcție. Această idee funcționează la fel pentru configurarea câmpurilor. Putem face ca toate câmpurile noastre să partajeze un apel invers și să-l facă să scoată tipul de câmp corect pe baza argumentelor pe care le transmitem. Să adăugăm câmpurile la metoda noastră de constructor. Puneți acest cod imediat după conectarea secțiunilor noastre în constructor:

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

Deoarece cunoașteți deja exercițiul, vă voi întoarce doar apelul pentru acțiunea noastră:

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

Argumentele din această funcție sunt similare cu cele din funcția secțiuni. Primul argument este identificatorul unic pentru câmp. A doua este eticheta care apare lângă câmp. În al treilea argument puteți vedea că apelez metoda field_callback ; vom crea acel apel invers în doar o secundă. A patra este pagina de opțiuni pe care dorim să o folosim ( $slug -ul nostru de mai devreme). Al cincilea argument este identificatorul unic pentru secțiunea căreia dorim să îi atribuim acest câmp.

Iată codul pentru apel invers în al treilea argument:

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

Aici copiez pur și simplu identificatorul unic al câmpului în nume, ID și funcția noastră get_option . Să vedem cum arată pagina noastră cu noul nostru câmp atașat:

Pagina noastră de setări cu primul nostru câmp.
Pagina de setare cu primul nostru câmp atașat.

Minunat, avem domeniul nostru pe pagină! Încercați să adăugați conținut la acesta și să apăsați pe Salvați modificările, voi aștepta aici...

ai facut-o? Dacă ați făcut totul până în acest moment, ar fi trebuit să primiți o eroare care spune ceva de genul ERROR: options page not found sau similar. Motivul pentru care se întâmplă acest lucru este de fapt o caracteristică de securitate a WordPress.

Vedeți, fără această caracteristică, un utilizator ar putea intra în HTML și ar putea schimba numele unui câmp în orice dorea, apăsând pe Salvare și ar putea introduce acea opțiune în baza de date cu orice nume i s-a dat (presupunând că este un numele opțiunii). Acest lucru ar putea permite oricărui utilizator să schimbe opțiunile de pe alte pagini (chiar și pe cele pe care în mod normal nu le-ar putea accesa) prin simpla introducere a numelui corect în câmp și apăsând pe Salvare - nu mișto.

Această problemă este rezolvată prin adăugarea unei funcții numită register_setting . Cu excepția cazului în care îi spui în mod specific WordPress, „Hei, acest câmp poate fi salvat pe această pagină”, WordPress nu va actualiza un câmp din baza de date. Deci, sub marcajul nostru de câmp, vom adăuga această nouă funcție. Iată cum arată apelarea după ce adăugăm codul:

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

Primul argument din noua funcție este pagina de opțiuni pe care vrem să salvăm câmpul ( $slug -ul de mai devreme), iar al doilea argument este câmpul pe care vrem să-l salvăm. Acum încercați să actualizați câmpul - a funcționat!

Felicitări! Tocmai ați salvat primul câmp folosind API-ul Setări WordPress. Acum, ce se întâmplă dacă vrem să avem niște tipuri diferite de câmpuri în loc de doar text? Să ne revedem apelul în câmpul nostru și să vorbim despre acea variabilă $arguments care este trecută în funcția noastră.

Argumente de câmp

Dacă intrăm în câmpul nostru callback și var_dump( $arguments ) vom obține o matrice goală. Ce dă? În apelarea secțiunii noastre, avem o grămadă de lucruri despre secțiune. Ei bine, aici se întâmplă ceva diferit. Dacă consultați documentația pentru add_settings_field , există un al cincilea argument care poate fi trecut în funcție. Această variabilă se corelează direct cu variabila $arguments din callback-ul nostru. Așa că vom dori să punem noile noastre lucruri acolo.

Dacă ne uităm la unul dintre câmpurile implicite dintr-o pagină de setări WordPress, putem vedea că există mai multe zone pe care le putem adăuga câmpului nostru pentru a obține o formatare implicită. Iată o captură de ecran a câmpului fus orar din pagina de setări generale:

Câmpul fus orar WordPress
Câmpul fus orar WordPress. (Vezi versiunea mare)

Folosind acest câmp ca punct de plecare, să trecem peste datele pe care dorim să le transmitem în câmpul nostru de apel invers.

  • Identificatorul unic
  • Eticheta pentru câmp (Fus orar în exemplu)
  • În ce secțiune ar trebui să intre
  • Tipul de câmp (text, zonă de text, selectare etc.)
  • În cazul în care există mai multe opțiuni, le vom dori
  • Poate un substituent dacă tipul de câmp acceptă unul
  • Text de ajutor (în dreapta câmpului din exemplu)
  • Text suplimentar (sub câmpul din exemplu)
  • Poate o selecție implicită, dacă există una

Din această listă putem configura o matrice asociativă de câmpuri și valori pe care le putem transmite în apel invers:

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

Deci primul lucru pe care îl avem aici este o variabilă numită $fields care va deține toate câmpurile pe care vrem să le creăm. În interiorul acestei matrice avem o altă matrice care deține datele specifice pentru fiecare câmp. Am configurat datele pentru a se potrivi exact cu lista noastră de mai sus. Apoi, parcurg fiecare câmp (vom adăuga mai multe în scurt timp) din matrice și adaug câmpul și îl înregistrez. La sfârșitul funcției add_settings_field , adaug și întreaga matrice de date pentru acel câmp specific, astfel încât să putem face unele lucruri în funcția de apel invers. Să aruncăm o privire la această funcție de apel invers aici:

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

În exemplul de mai sus, facem mai multe lucruri. Setăm valorile implicite pentru câmpurile dacă acestea sunt goale și adăugăm ajutorul și textul suplimentar. Cea mai importantă parte a codului nostru este însă declarația switch. În această declarație, vom sublinia modul în care argumentele noastre vor fi tratate în funcție de tipul de câmp pe care îl dorim.

De exemplu, dacă avem un câmp text, nu avem nevoie să avem mai multe opțiuni. Cu toate acestea, un meniu derulant <select> trebuie să aibă opțiuni pentru a funcționa corect. Deoarece avem tipuri de text deja configurate, haideți să rulăm acest cod și să vedem ce obținem.

Câmpul nostru a fost completat inclusiv substituent
Câmpul nostru a fost completat, inclusiv textul substituent. (Vezi versiunea mare)

Când încărcați pagina de setări a pluginului, ar trebui să vedeți câmpul de sus din această imagine. Partea de jos este ceea ce veți vedea dacă eliminați conținutul din câmp (adică substituentul). Dacă ar trebui să elimin argumentele helper sau supplimental din matricea noastră de câmpuri, acestea ar trebui să dispară pe pagina de setări. De asemenea, putem schimba argumentul section și deplasăm în jurul plasării câmpului în secțiuni.

OK, deci avem câmpuri de text; ce zici de unele tipuri de câmpuri mai complexe? Să aruncăm o altă privire asupra declarației noastre de comutare și să adăugăm opțiunea pentru zonele de text și selectările unice:

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

În codul de mai sus veți observa mai multe diferențe între fiecare dintre tipurile de câmp. Deși zonele de text sunt similare din punct de vedere funcțional cu câmpurile de text obișnuite, ele necesită un marcaj diferit. Selectați meniurile derulante sunt un cu totul alt animal din cauza opțiunilor. Trebuie să parcurgem opțiunile și valorile setate, stările selectate și etichetele. Deci, marcajul nostru este drastic diferit.

Acum că ne-am actualizat funcția de apel invers, să vedem cum s-au schimbat datele câmpului:

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

Iată trei câmpuri, fiecare folosind un tip de câmp diferit în pluginul nostru. Prima pe care am trecut-o deja. Al doilea este noul nostru câmp textarea . Putem trece aceiași parametri cu matricea (cu excepția UID-ului), dar o simplă modificare a tipului nostru și vom obține în schimb o textarea de text. Ultimul câmp din această matrice este meniul derulant select. Actualizarea principală aici este adăugarea matricei de opțiuni. Adăugăm o matrice asociativă simplă cu cheia matricei ca valoare a opțiunii HTML și eticheta. Folosind această matrice, iată cum arată câmpurile noastre:

Pagina noastră de setări după ce câmpurile sunt completate
Pagina noastră de setări cu câmpuri. (Vezi versiunea mare)

Aproape gata!

Acum avem o pagină de setări pentru plugin funcțională. Am configurat secțiunile pentru pagină, opțiunile, toate apelurile și am înregistrat câmpurile. Singurul lucru rămas este să ne aducem valorile setate în altă parte. Credeți sau nu, am făcut deja asta. În partea de sus a câmpului de apel invers, puteți vedea că verificăm valoarea bazei de date:

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

Putem folosi același cod în pluginul nostru (sau tema) și pur și simplu să trecem uid -ul în funcție. Deci, dacă aș vrea să obțin valoarea our_first_field , aș scrie pur și simplu:

 get_option('our_first_field')

Hei, presto! Avem pluginul nostru minunat și setările noastre minunate! Evident, am configurat doar câteva tipuri de câmpuri, dar am trecut și am adăugat mai multe în depozitul de cod pentru această abordare (în special câmpuri de text, parole, numere, zone de text, meniuri derulante de selectare, selectări multiple, butoane radio și casete de selectare).

Abordarea 2: Configurarea unui formular personalizat și a unui handler

În trecut, această abordare era singura modalitate de a adăuga pagini de setări. Înainte de WordPress 2.7, autorii de pluginuri trebuiau să-și creeze propriile formulare și handlere personalizate. Acest lucru a dus, evident, la o mulțime de erori și inconsecvențe între pluginuri. Deși această abordare este oarecum depreciată, este încă o opțiune viabilă în unele cazuri.

Pro

  • Puteți trimite formularul la personalizat și la distanță
  • Puteți ocoli unele dintre restricțiile încorporate ale API-ului Setări

Contra

  • Compatibilitatea trebuie să fie menținută de dezvoltator
  • Trebuie igienizat și validat manual

Când ar trebui să utilizați această abordare?

Utilizați această abordare atunci când trebuie neapărat să aveți un handler personalizat sau o interfață foarte personalizată. Probabil că puteți scăpa cu Abordarea 1 în cele mai multe cazuri, dar aveți mai multă flexibilitate cu validarea și manipularea folosind această metodă.

Noțiuni de bază

Înainte de a intra în detalii, trebuie să venim cu un scenariu în care am folosi un handler personalizat. De dragul simplității, să creăm un formular care va verifica un nume de utilizator și o adresă de e-mail. Am putea extrage datele dintr-o bază de date sau chiar dintr-un server la distanță. În acest caz, voi configura o matrice cu nume de utilizator și adrese de e-mail valide cu care să le verificăm. Vom stoca apoi valorile câmpurilor introduse de utilizator și le vom stoca în baza de date.

Crearea formularului

După cum am menționat anterior, vom urma aceiași pași pe care i-am făcut în „Crearea paginii noastre de plugin și setări”. Pentru această abordare ne vom configura câmpurile utilizând marcaj HTML static. Vom adăuga acest cod la apel invers din funcția plugin_settings_page_content astfel:

 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 }

Puteți vedea mai sus că doar adăugăm niște HTML static pentru câmpurile noastre. Duplicăm marcajul din paginile principale de setări WordPress. De asemenea, omitem acțiunea formularului, astfel încât acesta va trimite formularul la pagina curentă, spre deosebire de handlerul implicit options.php .

Înainte de a scrie handlerul nostru personalizat, să introducem câteva funcții de securitate rapide. Primul lucru pe care ar trebui să-l facem este să punem un nonce în forma noastră. Nonces va proteja împotriva tentativelor de falsificare a cererilor pe mai multe site-uri, ceea ce este similar cu falsificarea utilizatorilor sau atacurile de reluare. Să punem nonce în HTML-ul nostru:

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

wp_nonce_field va adăuga câteva câmpuri ascunse la formularul nostru; nonce şi referrer. Vom reveni la nonce când vom parcurge codul de gestionare.

Apoi trebuie să adăugăm un câmp pentru a detecta când formularul a fost actualizat. Putem face acest lucru adăugând pur și simplu un câmp ascuns în partea de sus a formularului nostru:

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

Acum putem pune un fragment de cod în partea de sus a paginii noastre pentru a detecta când este trimis formularul nostru și pentru a ne trimite la handlerul nostru personalizat:

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

Aici pur și simplu verificăm dacă câmpul ascuns updated a fost trimis și, dacă a fost, apelăm o metodă în pluginul nostru numită handle_form . Aici putem începe să scriem handlerul nostru personalizat.

Crearea handler-ului

Există câteva lucruri pe care trebuie să le verificăm în handler înainte de a gestiona efectiv datele din formular. Mai întâi trebuie să verificăm dacă nonceul nostru există și este 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 } }

Codul de mai sus verifică dacă nonce este corect. Dacă este nevalid, dăm utilizatorului un mesaj despre motivul pentru care formularul nu a fost actualizat. Dacă nonce există și este corect, ne putem ocupa de forma. Să scriem acum codul pentru handlerul nostru de formulare (acest cod va înlocui comentariul din fragmentul de mai sus):

 $valid_usernames = array( 'admin', 'matthew' ); $valid_emails = array( 'email@domain.com', 'anotheremail@domain.com' ); $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 }

Să parcurgem codul din această secțiune. Primele două rânduri sunt matricele de nume de utilizator/e-mailuri valide cu care vom verifica. Aceste valori ale matricei pot fi populate de oriunde.

Următoarele două rânduri sunt valorile pe care utilizatorul nostru le-a introdus în formular. Folosim funcțiile de igienizare încorporate pe care ni le oferă WordPress. Acest pas este important pentru a evita mai multe vulnerabilități cu formularele web. Apoi, verificăm dacă valorile furnizate de utilizatori sunt în matricea noastră de valori acceptabile. Dacă sunt, actualizați opțiunile formularului din baza de date. Acest pas ar putea fi înlocuit și cu un mecanism de stocare personalizat. De asemenea, oferim utilizatorului un mesaj că câmpurile lor au fost salvate. Dacă introducerea utilizatorului este nevalidă, îi spunem acest lucru.

Ultimul lucru pe care trebuie să-l facem este să arătăm câmpurile stocate în formular după ce au fost introduse. Vom face asta în același mod în care am prelua aceste câmpuri în altă parte în plugin: cu funcția get_option . Iată câmpurile după ce adăugăm codul corect:

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

Acum suntem gata să ne testăm formularul. Încercați să introduceți numele de utilizator admin și adresa de e-mail email@domain.com . Ar trebui să primiți următoarele în formularul dvs.:

Câmpurile salvate după ce introducem valorile corecte
Câmpurile salvate după ce introducem valorile corecte. (Vezi versiunea mare)

Dacă încercați să setați oricare dintre câmpuri la o valoare nevalidă, ar trebui să primiți un mesaj de eroare și câmpurile nu ar trebui să se actualizeze din cauza handlerului nostru personalizat.

Asta e pentru a doua noastră abordare! Acum ați configurat un formular personalizat și un handler pentru a vă gestiona câmpurile pluginului. Codul completat pentru această abordare poate fi găsit în depozitul acestui articol. Acum, să trecem la abordarea noastră finală.

Abordarea 3: Integrarea ACF (Câmpuri personalizate avansate) în pluginul dvs

Dacă nu ați folosit încă ACF by Elliot Condon, permiteți-mi să vă prezint. ACF este un manager de teren minunat pentru WordPress. Unul dintre cele mai bune lucruri despre acesta este interfața de configurare pe teren. Face destul de ușor să înregistrați câmpuri pentru un număr de pagini diferite din WordPress (cum ar fi postări, pagini, utilizatori, taxonomii, chiar și propriile pagini de opțiuni integrate). S-ar putea să vă gândiți „Nu pot să integrez pluginul altcuiva în al meu – asta e umbră!” dar domnul Condon înțelege situația dificilă a colegilor săi dezvoltatori și a planificat acest lucru în pluginul său. Puteți vedea documentația lui pe acest subiect, dar voi reitera o parte din ea aici. Să trecem peste reguli.

  1. În primul rând, dacă distribuiți un plugin gratuit, trebuie să utilizați versiunea gratuită a ACF. Asta pentru ca oamenii să nu poată pune mâna pe versiunea PRO din pluginul tău gratuit – asta nu ar fi grozav. Puteți folosi versiunea PRO în plugin-uri și teme premium fără nicio problemă, doar asigurați-vă că cumpărați licența de dezvoltator.
  2. În al doilea rând, nu modificați informațiile privind drepturile de autor ale ACF. Dă-i omului puțin credit!
  3. În cele din urmă, nu distribuiți cheia de licență cu pluginul dvs.

Acum, avantajele și dezavantajele acestei abordări:

Pro

  • Foarte ușor de integrat în teme și pluginuri
  • Puteți profita de câmpurile avansate care fac parte din ACF
  • Actualizările de cod și de securitate sunt gestionate de echipa ACF
  • ACF are suplimente grozave și suport dacă rămâneți blocat
  • Configurarea câmpurilor este super simplă datorită interfeței de utilizare a câmpurilor

Contra

  • Acces limitat la marcaj
  • Creează o dependență pentru pluginul sau tema dvs
  • Pentru a menține ACF actualizat, trebuie să îl mențineți actualizat în fișierele plugin/teme (mai multe informații mai jos)

Când ar trebui să utilizați această abordare?

Când doriți să construiți o interfață cu setări avansate foarte rapid și nu trebuie să personalizați aspectul și senzația.

Noțiuni de bază

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 (Vezi versiunea mare)

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. (Vezi versiunea mare)

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

Primele două linii ale funcției noastre sunt adăugarea scripturilor și stilurilor de care vom avea nevoie pentru câmpurile de setări. După aceea, configurăm opțiunile pentru formularul nostru. Puteți observa că valoarea din argumentul field_groups potrivește cu ID-ul din funcția noastră register_field_group . Pentru a vedea ceilalți parametri de configurare, aruncați o privire la documentația acf_form . Ultima linie din funcția noastră va reda de fapt forma.

Dacă încercați să încărcați pagina de setări acum, este posibil să vedeți că pagina este de fapt spartă. Acest lucru se datorează faptului că ACF trebuie să localizeze câteva variabile pentru JavaScript. Pentru a face acest lucru, trebuie să adăugăm un alt cârlig la constructorul nostru:

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

Acum trebuie să configuram apelul invers:

 public function add_acf_variables() { acf_form_head(); }

Puteți încerca să adăugați conținut și să salvați și ar trebui să funcționeze la fel ca celelalte două abordări ale noastre. Iată cum ar trebui să arate pagina noastră:

Formular ACF terminat
Formularul nostru ACF completat. (Vezi versiunea mare)

Există doar câteva articole de curățare pe care trebuie să le abordăm:

  • Poate doriți să ascundeți faptul că utilizați ACF pentru pluginul dvs. Dacă acesta este cazul, trebuie să ascundeți elementul de meniu Câmpuri personalizate . Puteți face acest lucru adăugând acest fragment la funcția dvs. de constructor:

     add_filter( 'acf/settings/show_admin', '__return_false' );
  • Ar trebui să eliminăm versiunea bazei de date a grupului nostru de câmpuri. Doar accesați secțiunea câmpuri personalizate și apăsați butonul de gunoi. Acest pas este opțional, deoarece va afecta doar mediul în care ați construit pluginul, dar ar putea introduce probleme dacă testați pluginul în același mediu.

Utilizarea câmpurilor ACF din pluginul dvs

Pentru a obține câmpurile ACF pe care le-ați creat, trebuie pur și simplu să utilizați funcția implicită ACF get_field . Prima opțiune ar trebui să fie ID-ul unic pentru câmp și al doilea argument setat la 'option' . Iată cum am obține câmpul Awesome Date :

 get_field( 'awesome_date', 'option' )

Si asta e. Acum ați configurat un plugin cu setări ACF! Puteți vizualiza codul pentru această abordare în depozit.

Concluzie

Deci iată-l: trei moduri de a vă face pluginurile configurabile. Mi-ar plăcea să aud despre pluginurile pe care le puteți crea folosind aceste metode. Încă o dată, am creat un depozit care găzduiește codul pentru fiecare dintre aceste abordări. Vă rugăm să nu ezitați să le oferiți și să le personalizați pentru a se potrivi nevoilor dvs.

În ceea ce privește preferințele mele personale pentru aceste abordări, tind să înclin spre Abordarea 1. Prefer să păstrez cât mai puține dependențe în pluginurile mele și puteți personaliza marcajul pentru a tema pagina de setări pentru proiecte personalizate. Pentru prototipuri rapide sau proiecte în care trebuie să configurez câmpuri foarte avansate, voi folosi ACF – dar adaugă un nivel de complexitate la gestionarea actualizărilor pluginurilor.

De asemenea, merită menționată propunerea pentru un API Fields de Scott Clark. Deși în prezent este încă o lucrare în desfășurare, API-ul ar permite, în esență, dezvoltatorilor de pluginuri și teme posibilitatea de a utiliza aceeași interfață ca și API-ul Customizer pentru a crea câmpuri de setări în alte zone ale panoului de administrare.

Alternative ACF

După cum sa subliniat în comentariile de mai jos, și pentru a oferi dezvoltatorilor alte opțiuni care sunt similare cu abordarea ACF, puteți verifica câteva alternative care pot oferi diferite caracteristici. Dacă aveți mai multe, vă rugăm să le trimiteți în comentariile de mai jos! Aici nu sunt într-o ordine anume:

  • CMB2 de WebDevStudios
  • Meta Box de Tran Ngoc Tuan Anh (Rilwis)