În acest tutorial, vom examina cu atenție sub capota textului widget WordPress pentru a descoperi procesul de crearea unui widget care pot fi adăugate la mai multe locații widget.
Dacă știți elementele de bază ale programării în PHP, crearea unui widget WordPress nu este deloc dificilă. Am acoperit elementele de bază într-un tutorial mai devreme, The Anatomy of a WordPress Plugin - este o idee bună să verificați că unul înainte de a citi mai departe, dacă nu ați construit un widget înainte.
În timp ce modul de bază al creării unui widget este suficient de bun pentru multe pluginuri, acesta are un dezavantaj major: widgetul poate fi adăugat într-un singur slot într-un blog.
Dacă adăugați widget-ul la unul din barele laterale, butonul widget "Add" dispare și widgetul nu poate fi adăugat la niciun alt slot înainte de al scoate de la primul.
În unele cazuri, aceasta nu este o problemă, deoarece natura widget-ului este că este afișată o singură dată. De exemplu, este destul de bine să listați arhiva blogului într-un singur loc în aspect. Dar există multe cazuri în care mai multe exemple pot fi foarte utile. Un astfel de exemplu este textul widget care vine bundled cu WordPress.
Textul widget este un widget simplu care vă permite să specificați un antet și un text, permițând, de asemenea, codul HTML și redă conținutul acestuia în bara laterală a blogului. Din cauza acestei simplități, widgetul poate fi folosit pentru o gamă largă de scopuri. De exemplu, în următoarea imagine - o captură de ecran din blogul meu personal - puteți vedea modul în care folosesc widgetul text în bara laterală pentru a afișa un text de întâmpinare și apoi din nou pentru a afișa unele anunțuri în partea de jos a barei laterale. În documentația WordPress se numesc widget-uri ca acesta "multi-widget".
Deoarece WordPress este un proiect open source, putem să explorăm codul sursă și să îl folosim ca referință pentru propriile noastre proiecte. Pentru acest tutorial, aceasta înseamnă că putem să aruncăm o privire mai atentă la widgetul Text și să vedem cum a fost implementat, folosindu-l ca exemplu pentru a transforma propriile noastre widget-uri în widget-uri multiple.
Primul pas este să căutați codul WordPress și să găsiți widget-ul textului. Este un pas interesant și vă recomand să verificați și alte fișiere aici și acolo pentru a obține o privire globală a ceea ce se întâmplă în interiorul platformei de blogging.
Dar dacă tocmai nu puteți aștepta să ajungeți la acțiune, iată unde veți găsi codul widget:
WordPress / wp-includes / widgets.php
Deschideți fișierul și derulați până la capătul său, în jurul liniei 1958 (în versiunea 2.7.1) și acolo, ascuns în mijlocul codului sursă, veți găsi un widget exemplu, comentat și etichetat "Model pentru widgetul multi (permite mai multe instanțe, cum ar fi widget-ul textului)".
La început, exemplul de cod poate arăta mai degrabă descurajant, așa că vom trece prin linia de linie, făcând sens ideilor în jurul cărora este construit modelul. Fragmentele de cod din acest tutorial au fost copiate din modelul exemplu, dar am făcut câteva mici modificări aici și acolo pentru a face codul mai ușor de urmărit (în principal, divizarea liniilor lungi la cele mai scurte). În afară de aceste ajustări mici, codul sursă este exact același lucru pe care îl veți găsi prin deschidere widgets.php
din baza de date WordPress.
Când utilizatorul apasă butonul "Salvați modificările" din meniul Widgets, WordPress colectează parametrii de formular din fiecare widget listat în barele laterale și le trimite la fiecare widget înregistrat. Această caracteristică este ceea ce face posibilă crearea mai multor widget-uri posibile: Întrucât funcția controlerului widget devine notificată pentru a salva o instanță widget, toți parametrii îi sunt transmise și poate actualiza fiecare instanță a acestui tip de widget dintr-o dată, adăugând altele noi și eliminând cele neutilizate după cum este necesar.
Vom analiza detaliile procesului de salvare într-o perioadă scurtă de timp, dar mai întâi, un loc bun pentru a începe să ne uităm la modul în care sunt stocate datele widget pentru un widget multiplu este să se uite la partea codului în care se utilizează datele . Iată codul pentru metoda utilizată pentru afișarea unei instanțe a widget-ului exemplu:
$ widget_args); $ widget_args = wp_parse_args ($ widget_args, array ('număr' => -1)); extract ($ widget_args, EXTR_SKIP); // Datele ar trebui să fie stocate ca array $ options = get_option ('widget_many'); dacă (! isset ($ opțiuni [$ number])) retur; echo $ before_widget; // Faceți chestii pentru acest widget, desenați date din opțiunile $ [$ number] echo $ after_widget; ?>
Primul parametru a trecut la funcția de redare widget, $ args
, conține setări widget generice, cum ar fi ceea ce ar trebui tipărit înainte și după widget și modul în care trebuie formatat titlul widgetului. Codul de pe linia 3 este folosit pentru a împărți aceste informații în variabilele locale, din care $ before_widget
și $ after_widget
sunt utilizate în exemplu.
Al doilea parametru, $ widget_args
este mai interesant pentru noi: conține id-ul instanței widget care trebuie redat. Linile 4 până la 7 există pentru a vă asigura că parametrul este în format corect și că, în cele din urmă, după extrage
apel pe linia 7, putem găsi indicele widget în variabila locală număr $
.
La fel ca setările widget-urilor pentru un widget simplu, de o singură dată, setările pentru o instanță widget sunt stocate ca o matrice care conține perechi cheie-valoare pentru fiecare setare. Dar, deoarece acum trebuie să stocăm mai multe instanțe, în loc să salvăm fiecare matrice cu propriul apel update_option
, le punem pe toate într-o singură matrice utilizând id-ul instanței (număr $
) ca index și apoi salvați întreaga chestie cu id-ul tipului de widget.
În exemplul de mai sus, avem un widget numit "widget_many
"și să spunem că am adăugat trei exemple de acest lucru pe bara laterală a blogului nostru. Atunci când redăm una dintre ele, primim mai întâi o matrice care conține toate widget_many
prin apel get_option ( 'widget_many');
(linia 10) și apoi găsiți datele pentru instanța curentă din matricea respectivă (linia 16).
Exemplul de cod din nu arată specificul a ceea ce trebuie să faceți cu datele, așa că haideți să ne uităm la widgetul text real pentru o mai bună înțelegere:
$ widget_args); $ widget_args = wp_parse_args ($ widget_args, array ('număr' => -1)); extract ($ widget_args, EXTR_SKIP); $ opțiuni = get_option ('widget_text'); dacă (! isset ($ opțiuni [$ number])) retur; $ title = apply_filters ('widget_title', $ opțiuni [$ number] ['title']); $ text = apply_filters ('widget_text', $ opțiuni [$ number] ['text']); ?>
Pe liniile 13 și 14, puteți vedea cum se citesc cei doi parametri necesari pentru widgetul text din opțiunile care utilizează număr $
ca id exemplu. Iar în următoarele zece linii, parametrii sunt afișați pe ecran.
Analizând funcția de redare widget, am descoperit acum elementele de bază din spatele salvării datelor pentru un widget multiplu:
Acum ne vom uita mai aproape și vom vedea trucurile și avertismentele implicate.
Folosind aceeași abordare ca înainte, vom examina acum funcția utilizată pentru afișarea și manipularea formularelor de setări și pentru a trece prin linia respectivă. Această funcție, widget_many_control
, este funcția care salvează setările și redă formularul de setări pentru widget-ul exemplu widget_many. Se numește o dată pentru fiecare widget_many
exemplu, trecând mereu id-ul de instanță $ widget_args
.
Deoarece funcția este o parte a procesului de depunere a formularului, $ _POST
array va conține toți parametrii care au fost trimise utilizând formularul de editare a widgetului.
$ widget_args); $ widget_args = wp_parse_args ($ widget_args, array ('număr' => -1)); extract ($ widget_args, EXTR_SKIP);
Pe primele linii ale funcției veți vedea ceva familiar (linii 6-9). Aceasta este aceeași bucată de cod care a fost folosită în funcția de randare pentru a vă asigura număr $
a fost inițializată cu id-ul numeric al instanței widget-ului curent.
Dar, după cum veți observa în curând, nu vom avea nevoie de acest index pentru nimic altceva decât redarea formularului de editare a widgetului, deoarece salvăm întotdeauna fiecare instanță a tipului de widget "widget_many" într-o singură buclă.
Apoi, vom prelua setările widgetului curent, creându-le dacă nu există:
$ opțiuni = get_option ('widget_many'); dacă (! is_array ($ opțiuni)) $ opțiuni = array ();
Când implementați propriul widget, nu uitați să schimbați cheia, widget_many
la id-ul propriului widget. În afară de aceasta, acest cod poate fi reutilizat ca atare. Pe liniile 2 și 3, codul are grija de cazul când adăugăm prima instanță widget de acest tip, creând o matrice de opțiuni goale pe care să o folosim.
Dacă setările au fost deja salvate cel puțin pentru o instanță, le obținem get_option
și poate continua actualizarea setărilor dacă a fost trimis un formular:
dacă ! $ actualizat &&! gol ($ _ POST ['sidebar']))
Linia de mai sus are două funcții: verifică dacă datele au fost postate ("!gol ($ _ POST [ 'Sidebar'])
") și se asigură că instanțele acestui tip de widget sunt gestionate o singură dată.
Sistemul widget solicită funcția de gestionare a widgeturilor o singură dată pentru fiecare instanță widget, dar pentru că trebuie să avem grijă de lucruri cum ar fi adăugarea și eliminarea instanțelor noi de widgeturi, nu putem face acest lucru fără să știm toate widgeturile de acest tip care există. Acesta este motivul pentru care abordarea este de a actualiza fiecare instanță widget de acest tip la primul eveniment și apoi setați variabila globală $ actualizat
la adevărat, astfel încât următoarea instanță să nu facă din nou actualizarea.
// ne spune ce bara laterală pentru a pune datele în $ sidebar = (string) $ _POST ['sidebar']; $ sidebars_widgets = wp_get_sidebars_widgets (); dacă (isset ($ sidebars_widgets [$ sidebar])) $ this_sidebar = & $ sidebars_widgets [$ sidebar]; altfel $ this_sidebar = array (); ($ this_sidebar ca $ _widget_id) $ widget = $ wp_registered_widgets [$ _ widget_id]; dacă '(widget_many' == $ widget ['callback'] && isset ($ widget ['params'] [0] ['number'])) $ widget_number = $ widget [ număr']; dacă (! in_array ("multi- $ widget_number", $ _POST ['widget-id'])) dezactivat ($ opțiuni [$ widget_number]); // Compilați datele din $ widget_many_instance $ widget_data = (array) $ _POST ['widget-many']; foreach ($ widget_data ca $ widget_number => $ widget_many_instance) if (! isset ($ widget_many_instance ['ceva']) && isset ($ optiuni [$ widget_number])) // user clicked cancel continua; $ something = wp_specialchars ($ widget_many_instance ['ceva']); $ opțiuni [$ widget_number] = array ('ceva' => $ ceva); update_option ('widget_many', opțiuni $); $ updated = true; // ca să nu trecem prin asta de mai multe ori
Acest fragment de cod privește mai întâi toate widget-urile stocate în bara laterală actualizată (linii 2-8) și apoi trece prin lista eliminând tot ce corespunde id-ului widget al acestui tip de widget (linii 10-18).
$ _POST ( "sidebar")
(linia 2) conține id-ul bara laterală. În acest fel, dacă utilizatorul a eliminat un widget, acesta va fi șters și din date. Și ștergând totul, ne asigurăm că nu lăsăm în mod accidental duplicate, de exemplu dacă id-ul unui widget sa schimbat între actualizări.
După ce eliminăm totul, începem să adăugăm widget-urile trimise de utilizator. În formularul postat, există o matrice care conține toate datele pentru fiecare instanță a tipului de widget. Matricea este organizată astfel:
['widget-many'] => [0] => paramuri pentru instanța widget 0 (array), [1] => paramuri pentru instanța widget 1 (array), ...
Pe liniile 23-31, codul buclează datele de expediere widget și creează setările pentru fiecare instanță (liniile 29 și 30). Deoarece acesta este doar un exemplu de cod, partea de salvare folosește date de tip "placeholder", cum ar fi "ceva". Deci, să aruncăm o privire la widgetul text pentru a vedea cum funcționează acest lucru cu date reale:
$ title = strip_tags (stripslashes ($ widget_text ['title'])); dacă (current_user_can ('unfiltered_html')) $ text = stripslashes ($ widget_text ['text']); altceva $ text = stripslashes (wp_filter_post_kses ($ widget_text ['text'])); $ opțiuni [$ widget_number] = compact ("titlu", "text");
Text widget-ul are doi parametri: titlu
și text
. $ widget_text
variabilă în această bucată de cod este folosit în același mod ca $ widget_many_instance
în codul exemplu pe care l-am urmărit: conține datele trimise pentru o anumită instanță a widget-ului.
În exemplul widget text, veți vedea, de asemenea, câteva caracteristici de securitate interesante, pe care ați putea dori să le priviți mai mult când vă dezvoltați widget-urile proprii. Pentru acest tutorial, totuși, este suficient să observăm conținutul variabilelor titlu $
și $ Text
sunt citite din matricele postate și apoi stocate ca matrice la opțiunile widget-ului de pe linia 6.
Dacă vă întrebați compact()
funcția, este opusul extrage()
, și ia variabilele locale ale căror nume au fost transmise ca parametri și le transformă într-o matrice cu numele ca chei.
În cele din urmă, noul opţiuni de $
array este stocată ca date pentru widget, widget_many
în exemplul de cod sau widget_text
în widgetul text, utilizând update_option ()
funcţie.
Ultimul lucru rămas în funcția de setări widget este desenarea formularului pentru această instanță widget. Acest formular nu este redat pe ecran așa cum este, dar WordPress îl convertește într-o formă reală mai târziu, folosind unele magie JavaScript. Codul de mai jos este din codul șablonului, așa că îl folosește $ ceva
pentru a reprezenta datele widgetului. În widgetul text este înlocuit cu titlu $
și $ Text
, și în widget-ul dvs. cu tot ce aveți nevoie pentru a salva.
Este important de observat că, deși salvarea este făcută pentru fiecare instanță dintr-o dată, formatul redat aici este doar pentru un singur exemplu. Aici vom folosi id-ul de instanță widget citit la începutul funcției.
dacă -1 == $ $) $ ceva = "; $ număr = '% i%'; altceva $ something = attribute_escape ($ opțiuni [$ number] ['ceva']);
Pe liniile de mai sus, widget-ul verifică mai întâi dacă a fost dat sau nu un număr de widget valabil. Dacă nu, și număr $
a fost setat la valoarea implicită, -1, toate datele ar trebui să fie setate la valorile implicite. În caz contrar, vom obține datele de la opţiuni de $
și folosiți-o pentru a popula formularul cu setările curente. Acesta este un lucru frumos de facut astfel incat utilizatorul nu va trebui sa inceapa intotdeauna sa editeze widgetul dintr-o ardezie goala.
Apoi, formularul în sine este construit astfel încât să poată fi citit într-o matrice atunci când este postat în codul de manipulare a widgetului: Intrările de formă sunt numite urmând modelul Widget multe [numărul $] [ceva]
Unde număr $
este numărul acestei instanțe widget și ceva
este numele parametrului care trebuie salvat. WordPress analizează apoi această structură în matrice descrisă mai devreme când utilizatorul trimite formularul.
Formularul nu are un buton de trimitere deoarece toate widgeturile sunt salvate folosind același buton de trimitere furnizat de WordPress.
Pentru ca WordPress să afișeze un widget în lista de widgeturi, trebuie să-l înregistrezi spunând WordPress ce funcții trebuie să utilizeze pentru redarea widgetului și a formularului de setări. Modul în care se face acest lucru pentru dispozitivele multi-widget nu este diferit de widgeturile obișnuite. Singura diferență este în modul în care este definită idul widgetului: In $ control_ops
(linia 7), le spunem WordPress pentru a activa mai multe instanțe și pentru a atașa toate instanțele widget-uri cu pornirea unui id "mulți"
la acest tip widget.
funcția widget_many_register () if (! $ options = get_option ('widget_many')) $ opțiuni = array (); $ widget_ops = array ('classname' => 'widget_many', 'description' => __ ('Widget care permite mai multe instanțe')); $ control_ops = array ('lățime' => 400, 'înălțime' => 350, 'id_base' => 'multe'); $ name = __ ("Multe"); $ registered = false; foreach (array_keys ($ opțiuni) ca $ o) // Widgeturile vechi pot avea valori nula dintr-un anumit motiv dacă (! isset ($ opțiuni [$ o] ['ceva'])) continuă; // $ id ar trebui să arate ca $ id_base - $ o $ id = "many- $ o"; // Niciodată niciodată nu traduceți niciodată un id $ registered = true; wp_register_sidebar_widget ($ id, $ nume, 'widget_many', $ widget_ops, array ('număr' => $ o)); wp_register_widget_control ($ id, $ nume, 'widget_many_control', $ control_ops, array ('număr' => $ o)); // Dacă nu există nici unul, vom înregistra // existența widgetului cu un șablon generic dacă (! $ Înregistrat) wp_register_sidebar_widget ('many-1', $ name, 'widget_many', $ widget_ops, array (' > -1)); wp_register_widget_control ('multe-1', $ nume, 'widget_many_control', $ control_ops, array ('număr' => -1)); // Aceasta este importantă add_action ('widgets_init', 'widget_many_register');
În funcția de mai sus, înregistrăm mai întâi toate widgeturile existente de acest tip, sărind cele care nu au date valide (linii 11-23) și apoi dacă nu există încă o instanță disponibilă, înregistrați una implicită pentru a vă asigura că widget-ul este înregistrat și disponibil în bara laterală (linii 27-32).
Ca ultimul pas crucial, pe linia 34, am prins funcția de inițializare a widgetului la widgets_init
astfel încât WordPress să o numească când este timpul să inițializați toate widgeturile. Fără această funcție, nu am vedea nicio funcționalitate a widget-ului pe care tocmai l-am analizat, deoarece nici o parte a codului nu va fi apelată vreodată.
În fragmentele de mai sus, am lăsat în mod deliberat o parte din cod pentru a face lucrurile mai ușor de citit, astfel încât să nu puteți copia piesele și să le puneți laolaltă. În schimb, ar trebui să mergeți și să copiați același cod din instalarea WordPress.
După aceea, trebuie doar să vă puneți în funcțiune propriile funcții și acolo aveți: propriul multi-widget.