Elementele de meniu, paginile și taxonomiile (ierarhice) sunt toate exemplele de date cu o structură arborescentă: termenii pot avea părinți, copii și frați. De obicei, am dori să reflectăm această structură în marcajul HTML. Pentru a afișa un meniu, de exemplu, dorim ca HTML să fie o listă a legăturilor "de nivel superior", cu liste imbricate ale copiilor lor, care conțin ele însele listele imorale ale copiilor lor și așa mai departe. Acest tutorial vă va ghida printr-o clasă pe care WordPress o oferă, ceea ce face ca această marcă să fie extrem de simplă.
Clasa Walker este o clasă abstractă concepută pentru a ajuta la traversarea și afișarea elementelor care au o structură ierarhică (sau copac). În realitate nu "face" (în sensul generării HTML) orice. Pur și simplu urmărește fiecare ramură a copacului tău: trebuie să fie extinsă de alte clase care să-i spună ce să facă pentru fiecare element pe care îl întâlnește. WordPress oferă propriile clase de extindere, cum ar fi:
Walker_Nav_Menu
- pentru afișarea meniurilor HTML pentru navigareWalker_Page
- pentru afișarea unei liste de paginiWalker_Category
- pentru afișarea unei liste de termeni de taxonomie.Fiecare dintre aceste clase extinde clasa Walker dictând pur și simplu ceea ce scoate clasa la fiecare element și nivel al arborelui. Pentru a deștima această clasă, vom analiza principalele sale metode și câteva exemple de utilizare a acesteia. Clasa însăși poate fi găsită aici.
Mers pe jos
plimbare ($ elemente, $ max_depth)
Clasa Walker este lansată cu ajutorul metodei Walk și această metodă returnează codul HTML odată ce a fost generat. Acceptă două argumente:
$ max_depth
- stabilește câte generații analizăm$ args
. Acest lucru este apoi trecut la alte metode din clasăMetoda de plimbare individualizează elementele "de nivel superior" - cele fără părinți - și le plasează într-o singură matrice. Ceilalți, copiii, sunt plasați într-o a doua matrice în care cheia reprezintă ID-ul părintelui său (este o matrice bidimensională deoarece un părinte poate avea mai mulți copii):
$ children_elements = array ('1' => array () // Array de elemente corespunzătoare copiilor de 1, '4' => array () // Array de elemente corespunzătoare copiilor de 4);
Acesta apoi buclele prin fiecare dintre elementele părinte la rândul său și aplică metoda display_element
.
Display_Element
display_element (elementul $, & $ children_elements, $ max_depth, $ depth = 0, $ args, & output)
Așa cum sugerează și numele display_element
este responsabil pentru afișarea unui element în arborele nostru. De fapt, el numește mai multe funcții pentru a face acest lucru. Aceste funcții sunt în mod deliberat lăsate goale în clasa Walker - și acestea sunt modificate în clasele de extindere, deoarece determină HTML-ul real returnat. Acestea includ:
start_lvl
- o funcție de returnare a codului HTML pentru începutul unui nou nivel. În cazul listelor, aceasta ar fi începutul unei noi "sub-liste", și astfel ar fi responsabil pentru returnarea
etichetăend_lvl
- numit atunci când am terminat un nivel. În exemplul din meniul de navigare, această funcție este responsabilă pentru încheierea sub-listei cu o etichetă a listei de închidere
start_el
- funcția responsabilă pentru afișarea elementului curent pe care suntem. În cazul meniurilor, aceasta înseamnă că
tag și link-ul elementului.end_el
- a fost afișată funcția numită după un element și toți copiii ei. Pentru exemplul nostru de meniuri, aceasta înseamnă returnarea unei închideri
Deci ce face? display_element
de fapt face? De fapt, acolo are loc toată magia clasei Walker. Mai întâi, trebuie să aruncăm o privire asupra argumentelor pe care ni le oferim:
$ element de
- acesta este elementul pe care suntem în prezent pe copacul nostru$ children_elements
- o serie de toate elemente de copil (nu doar copii ai elementului menționat mai sus). Aceasta este a doua matrice formată în mers pe jos
și cheile sunt ID-urile părintelui.$ max_depth
- cât de departe ne este permis să explorăm$ adâncime
- cât de departe suntem în prezent$ args
- opțional argumente (menționate mai devreme)$ ieșire
- HTML până acum. Acest lucru este adăugat în timp ce explorăm mai mult din copac. display_element
primul apel start_el
care este responsabil pentru afișarea elementului. Exact cum face acest lucru depinde de context. Pentru un meniu derulant, poate fi sau pentru un meniu de navigare
. Observați că încă nu există nici o etichetă de închidere. Dacă acest element are copii, trebuie să le afișăm mai întâi astfel încât să fie imbricate în interiorul acestui element ...
Așa că, în continuare, se verifică dacă elementul curent pe care avem parte are copii și că nu am ajuns la adâncimea maximă. Dacă este așa, explorăm pe rând fiecare dintre copii, sunând display_element
pentru fiecare dintre ele (cu argumentul de adâncime incrementat de unul). În felul acesta display_element
recursiv se numește până ajungem la fund.
Să presupunem că am ajuns la partea de jos (un element fără copii sau adâncimea maximă), apoi sună end_el
care adaugă eticheta de închidere. Acolo este instanța curentă display_element
se termină și ne mutăm înapoi la părintele care aplică display_element
la copilul următor, până când am procesat fiecare dintre copiii săi. Când părintele nu mai are copii, ne mutăm înapoi în copac și așa mai departe, până când fiecare ramură este explorată. Confuz? Este o diagramă pe care sper că o va clarifica:
Utilizarea clasei Walker face ca afișarea datelor personalizate ierarhice să fie foarte simplă. Să presupunem că aveți o serie de obiecte, cu "eticheta
","PARENT_ID
' și 'object_id
"pe care doriți să afișați o listă cu. Acest lucru poate fi realizat cu ușurință cu o clasă foarte simplă:
Notă: Clasa de extindere este responsabilă pentru stabilirea unde se găsește ID-ul unui element și cel al părintelui său.
clasa Walker_Simple_Example extinde Walker // Setați proprietățile elementului care dă ID-ul elementului curent și al părintelui său var $ db_fields = array ('parent' => 'parent_id', 'id' => 'object_id'); // Afișează începutul unui nivel. De exemplu '
Puteți extinde clasele Walker pentru a schimba conținutul afișat, pentru a modifica codul HTML generat sau chiar pentru a împiedica afișarea anumitor ramuri. Funcții cum ar fi:
wp_nav_menu
wp_list_pages
wp_list_categories
Oferiți-vă o opțiune pentru a vă specifica propria clasă Walker personalizată - permițându-vă să vă modificați aspectul cu o ușurință relativ ușoară, specificând propria clasă Walker personalizată. În multe cazuri, este mai ușor să extindeți o extensie adecvată pentru walker, mai degrabă decât clasa Walker în sine.
Să presupunem că doriți să aveți un submeniu secundar care este legat de meniul principal. Acest lucru poate lua forma unor link-uri care se situează chiar sub meniul principal sau într-o bară laterală care afișează numai elementele din meniul "descendent" ale paginii curente "de nivel superior". Ca exemplu din diagrama de mai sus, dacă suntem pe sub-paginile "Arhiva", "Autor" sau "Știri", dorim să afișăm toate link-urile de mai jos "Arhiva". De cand Walker_Nav_Menu
face majoritatea ceea ce vrem, vom extinde această clasă mai degrabă decât clasa Walker. Acest lucru ne salvează mult efort, deoarece Walker_Nav_Menu
adaugă clasele corespunzătoare ("actual
","curent-strămoș
"etc.) la legăturile relevante. Vom extinde Walker_Nav_Menu
walker pentru a schimba ușor logica și a împiedica afișarea oricăror linkuri de nivel superior sau a oricarei descendenți ai paginilor "non-root".
Mai întâi de toate, în fișierele șablonului, vom folosi wp_nav_menu ()
funcționează de două ori, indicând la fel locație temă (O voi numi "primar
„). Dacă nu aveți o locație tematică înregistrată deja, ar trebui să citiți acest articol. Indiferent de locația temei pe care o utilizați, ar trebui să salvați un meniu în acea locație. Vom afișa acest meniu de două ori. Mai întâi, ori de câte ori doriți ca meniul dvs. "de nivel superior" să apară:
wp_nav_menu (array ('theme_location' => 'primar', 'adâncime' => 1));
Apoi, din nou, cu un walker personalizat, să afișați numai paginile (relevante) pentru copii.
wp_nav_menu (array ('theme_location' => 'primar', 'walker' => new SH_Child_Only_Walker (), 'depth' => 0));
În primul rând, nu vrem să afișăm părinți de nivel superior. Amintiți-vă că funcția responsabilă de deschidere tag-ul și link-ul este
start_el
și funcția responsabilă de închidere eticheta este
end_el
. Pur și simplu verificăm dacă suntem la nivelul părintelui. Dacă suntem, nu facem nimic. În caz contrar, vom continua "ca normal" și vom apela funcția din Walker_Nav_Menu
clasă.
// Nu imprimați elementul de nivel superior funcția start_el (& output, $ item, $ depth = 0, $ args = array ()) if (0 == $ depth) retur; părinte :: start_el (& $ output, $ item, $ depth, $ args); funcția end_el (& output, $ item, $ depth = 0, $ args = array ()) if (0 == $ adâncime) retur; părinte :: end_el (& $ output, $ item, $ depth, $ args);
Extinde display_element
. Această funcție este responsabilă pentru deplasarea în jos a ramurilor. Vrem să o oprim în urmele sale dacă suntem la nivelul de sus și nu pe legătura curentă curentă. Pentru a verifica dacă sucursala pe care ne aflăm este "curentă", verificăm dacă elementul are oricare dintre următoarele clase: "curent-meniu-element
","curent-meniu-părinte
","curent-meniu-strămoș
'.
// Urmăriți numai o funcție de ramură display_element ($ element, & $ children_elements, $ max_depth, $ depth = 0, $ args, & $ output) // Verificați dacă elementul este clasa curentă $ current_element_markers = array 'current-menu-item', 'current-menu-parent', 'current-menu-strămoș'); $ current_class = array_intersect ($ curent_element_markeri, $ element-> clase); // Dacă elementul are o clasă "curentă", este un strămoș al elementului curent $ ancestor_of_current =! Empty ($ current_class); // Dacă aceasta este o legătură de nivel superior și nu un curent sau un strămoș al elementului de meniu curent - opriți aici. dacă (0 == adâncime &&! $ ancestor_of_current) retur; părinte :: display_element ($ element, & $ children_elements, $ max_depth, $ depth, $ args, & $ output);
Acum extindem start_lvl
și end_lvl
funcții. Acestea sunt responsabile pentru ieșirea HTML care înfășoară un nivel (în acest caz,
Etichete). Dacă suntem la cel mai înalt nivel, nu vrem să afișăm aceste etichete (după ce tot conținutul nu va fi afișat).
// nu înfășurați funcția de nivel superior start_lvl (& $ output, $ depth = 0, $ args = array ()) dacă (0 == $ depth) retur; părinte :: start_lvl (& $ output, $ depth, $ args); funcția end_lvl (& $ output, $ depth = 0, $ args = array ()) if (0 == $ depth) întoarcere; părinte :: end_lvl (& $ output, $ depth, $ args);
Această clasă în întregime:
clasa SH_Child_Only_Walker prelungește Walker_Nav_Menu // Nu porniți funcția de nivel superior start_lvl (& $ output, $ depth = 0, $ args = array ()) dacă (0 == $ depth) return; părinte :: start_lvl (& $ output, $ depth, $ args); // Nu întrerupeți funcția de nivel superior end_lvl (& output, $ depth = 0, $ args = array ()) if (0 == $ depth) return; părinte :: end_lvl (& $ output, $ depth, $ args); // Nu imprimați elementul de nivel superior funcția start_el (& $ output, $ item, $ depth = 0, $ args = array ()) dacă (0 == $ depth) retur; părinte :: start_el (& $ output, $ item, $ depth, $ args); funcția end_el (& output, $ item, $ depth = 0, $ args = array ()) if (0 == $ adâncime) retur; părinte :: end_el (& $ output, $ item, $ depth, $ args); // Urmăriți numai o funcție de sucursală display_element ($ element, & $ children_elements, $ max_depth, $ depth = 0, $ args, & $ output) // Verificați dacă elementul este clasa curentă $ current_element_markers = array ("curent-meniu-element", "curent-meniu-părinte", "curent-meniu-strămoș"); $ current_class = array_intersect ($ curent_element_markeri, $ element-> clase); // Dacă elementul are o clasă "curentă", este un strămoș al elementului curent $ ancestor_of_current =! Empty ($ current_class); // Dacă aceasta este o legătură de nivel superior și nu un curent sau un strămoș al elementului de meniu curent - opriți aici. dacă (0 == $ depth &&! $ ancestor_of_current) returnează părintele :: display_element ($ element, & $ children_elements, $ max_depth, $ depth, $ args, & output);
După ce înțelegeți cum funcționează clasa walker, puteți să o extindeți (sau extensiile existente ale WordPress) pentru a modifica modul în care sunt afișate datele dvs. ierarhice. De exemplu, puteți: