Menyelementer, sider og (hierarkiske) taksonomier er alle eksempler på data med en treaktig struktur: vilkårene kan ha foreldre, barn og søsken. Vanligvis vil vi gjenspeile denne strukturen i HTML-oppslaget. For å vise en meny, for eksempel, vil vi at HTML-en skal ha en liste over "toppnivå" -koblinger, med nestede lister over sine barn, som selv inneholder nestede lister over sine barn, og så videre. Denne opplæringen vil lede deg gjennom en klasse WordPress gir som gjør at denne oppmerkningen blir ekstremt enkel.
Walker-klassen er en abstrakt klasse designet for å hjelpe til med å krysse og vise elementer som har en hierarkisk struktur (eller tre). Det gjør egentlig ikke "gjør" (i den forstand at det genereres HTML) hva som helst. Det sporer bare hver gren av ditt tre: det må utvides av andre klasser som forteller det hva du skal gjøre for hvert element det kommer over. WordPress tilbyr sine egne utvidede klasser, for eksempel:
Walker_Nav_Menu
- for visning av HTML for navigasjonsmenyerWalker_Page
- for å vise en liste over siderWalker_Category
- for å vise en liste over taksonomiske vilkår.Hver av disse klassene utvider Walker-klassen ved bare å diktere hva klassen gir ut på hvert element og nivå av treet. For å de-mystify denne klassen skal vi se på de viktigste metodene og et par eksempler på hvordan du bruker den. Selve klassen finnes her.
Gå
gå ($ elementer, $ max_depth)
Walker-klassen blir sparket av med gå-metoden, og det er denne metoden som returnerer HTML-en gang den er blitt generert. Den aksepterer to argumenter:
$ MAX_DEPTH
- angir hvor mange generasjoner vi undersøker$ args
. Dette går da videre til andre metoder i klassenGåmetoden utpeker elementene "toppnivå" - de uten foreldre - og plasserer dem i en gruppe. Resten, barna, er plassert i et andre array hvor nøkkelen er ID for foreldrene (det er et todimensjonalt utvalg som en forelder kan ha flere barn):
$ children_elements = array ('1' => array () // Array av elementer som svarer til barn av 1, '4' => array () // Array of elements corresponding to children of 4);
Det løkker så gjennom hver av de overordnede elementene i sin tur og bruker metoden display_element
.
Display_Element
display_element ($ element, & $ children_elements, $ max_depth, $ deep = 0, $ args og $ output)
Som navnet antyder display_element
er ansvarlig for å vise et element i vårt tre. Faktisk kaller det flere funksjoner for å gjøre dette. Disse funksjonene er bevisst tomt i Walker-klassen - og det er disse som endres i de forlengende klassene, da de bestemmer den faktiske HTML returnerte. Disse inkluderer:
start_lvl
- en funksjon for å returnere HTML for starten av et nytt nivå. Når det gjelder lister, vil dette være starten på en ny "underliste", og det ville være ansvarlig for å returnere
stikkordend_lvl
- ringte når vi har avsluttet et nivå. I navigasjonsmenyeksemplet er denne funksjonen ansvarlig for å avslutte underlisten med en lukkeliste
start_el
- funksjonen som er ansvarlig for visning av det nåværende elementet vi er på. Når det gjelder menyer, betyr dette
tag og elementets lenke.end_el
- funksjonen som kalles etter et element, og alle det er barn, har blitt vist. For menyeksemplet betyr dette at vi returnerer en avslutning
Så hva gjør display_element
faktisk gjør? Det er faktisk hvor all den magiske Walker-klassen finner sted. Først kan vi se på hvilke argumenter den gir:
$ element
- Dette er elementet vi for tiden er på på treet vårt$ children_elements
- en rekke av alle barnelementer (ikke bare barn av elementet som er nevnt ovenfor). Dette er den andre gruppen som er dannet i gå
metode og nøklene er foreldrenes IDer.$ MAX_DEPTH
- hvor langt ned har vi lov til å utforske$ dybde
- hvor langt ned er vi for øyeblikket$ args
- valgfrie argumenter (nevnt tidligere)$ utgang
- HTML-koden hittil. Dette legges til når vi undersøker mer av treet. De display_element
Metode første samtaler start_el
som er ansvarlig for å vise elementet. Nøyaktig hvordan det avhenger av konteksten. For en rullegardinmeny kan det være eller for en navigasjonsmeny det kan
. Legg merke til at det ikke er noen lukkemerker ennå. Hvis dette elementet har barn, må vi vise dem først slik at de er nestet inne i dette elementet ...
Så det sjekker om det nåværende elementet vi er på, har noen barn, og at vi ikke har nådd maksimal dybde. I så fall undersøker vi hver av barna i sin tur ved å ringe display_element
for hver av dem (med dybdeargumentet økt med en). På denne måten display_element
rekursivt kaller seg til vi når bunnen.
Anta at vi har nådd bunnen (et element uten barn eller maksimal dybde), da ringer det end_el
som legger til lukkekoden. Der er nåværende forekomst av display_element
fullfører og vi flytter tilbake til den overordnede som gjelder display_element
til neste barn, til vi har behandlet hver av sine barn. Når foreldrene ikke har flere barn igjen, beveger vi oss tilbake på treet, og så videre til hver gren blir utforsket. Forvirret? Han er et diagram som jeg håper vil klargjøre ting:
Ved å bruke Walker-klassen blir det enkelt å vise tilpassede hierarkiske data. Anta at du har en rekke objekter, med 'merkelapp
','PARENT_ID
'og'object_id
'egenskaper som du ønsker å vise en liste over. Dette kan nå enkelt oppnås med en veldig enkel klasse:
Merk: Den utvide klassen er ansvarlig for å finne hvor du skal finne et elements ID og dets forelder.
klasse Walker_Simple_Example utvider Walker // Angi egenskapene til elementet som gir IDen til gjeldende element og dets forelder var $ db_fields = array ('parent' => 'parent_id', 'id' => 'object_id'); // Viser start av et nivå. E.g '
Du kan forlenge walkerklassen for å endre hvilket innhold som vises, endre HTML generert eller til og med forhindre at enkelte grener blir vist. Funksjoner som:
wp_nav_menu
wp_list_pages
wp_list_categories
Gi mulighet til å spesifisere din egen tilpassede Walker-klasse - slik at du kan endre utseendet ditt relativt enkelt ved å spesifisere din egen tilpassede walker-klasse. I mange tilfeller er det faktisk lettere å utvide en passende walkerforlengelse, i stedet for Walker-klassen selv.
Anta at du vil ha en sekundær (under) -meny som er relatert til hovedmenyen. Dette kan ta formen av koblinger som ligger like under hovedmenyen eller i en sidefelt som bare viser menyelementene "etterkommere" på den nåværende siden på toppnivå. Som et eksempel fra diagrammet ovenfor, hvis vi er på underarkivet 'Arkiv', 'Forfatter' eller 'Nyheter', vil vi gjerne vise alle linkene under 'Arkiv'. Siden Walker_Nav_Menu
gjør det meste av det vi vil, skal vi utvide den klassen i stedet for Walker-klassen. Dette sparer oss mye arbeid, siden Walker_Nav_Menu
legger til de riktige klassene ('nåværende
','strøm stamfar
'etc) til de aktuelle linkene. Vi skal forlenge Walker_Nav_Menu
Walker-klassen for å endre logikken litt, og forhindre at den viser noen toppnivå-linker eller noen av etterkommerne til "non-root" -sidene.
Først og fremst, i malen filer, vil vi bruke wp_nav_menu ()
Fungerer to ganger, peker på det samme tema sted (Jeg skal kalle dethoved~~POS=TRUNC
'). Hvis du ikke har et temaoppsett registrert, bør du lese denne artikkelen. Uansett hvilket temaområde du bruker, bør du lagre en meny til den plasseringen. Vi skal vise denne menyen to ganger. Først, uansett hvor du vil at menyen på toppnivå skal vises:
wp_nav_menu (array ('theme_location' => 'primær', 'dybde' => 1));
Deretter igjen, med en egendefinert walker, for å vise bare (relevante) barnesider.
wp_nav_menu (array ('theme_location' => 'primær', 'walker' => ny SH_Child_Only_Walker (), 'dybde' => 0));
Først av alt ønsker vi ikke å vise foreldre på toppnivå. Husk at funksjonen som er ansvarlig for åpningen tag og lenken er
start_el
og funksjonen som er ansvarlig for avslutningen tag er
end_el
. Vi kontrollerer bare om vi er på foreldre nivå. Hvis vi er, gjør vi ingenting. Ellers fortsetter vi som normalt og kaller funksjonen fra Walker_Nav_Menu
klasse.
// Ikke skriv på toppnivåelementfunksjonen start_el (& $ output, $ item, $ depth = 0, $ args = array ()) hvis (0 == $ dybde) tilbake; foreldre :: start_el (& $ utgang, $ element, $ dybde, $ args); funksjon end_el (& $ output, $ item, $ depth = 0, $ args = array ()) hvis (0 == $ dybde) tilbake; foreldre :: end_el (& $ output, $ item, $ depth, $ args);
Vi utvider display_element
. Denne funksjonen er ansvarlig for å reise nedover grenene. Vi vil stoppe det i sporene hvis vi er på toppnivå og ikke på den nåværende rotkoblingen. For å sjekke om grenen vi er på, er 'nåværende', kontrollerer vi om varen har noen av følgende klasser: 'gjeldende menypost
','current-meny-foreldre
','strøm-menu-stamfar
'.
// Bare følg ned en grenfunksjon display_element ($ element, & $ children_elements, $ max_depth, $ deep = 0, $ args, og $ output) // Sjekk om elementet som en 'nåværende element'-klasse $ current_element_markers = array 'nåværende meny-element', 'nåværende meny-forelder', 'nåværende meny-forfader'); $ current_class = array_intersect ($ current_element_markers, $ element-> classes); // Hvis elementet har en 'nåværende' klasse, er det en forfedre av det nåværende elementet $ ancestor_of_current =! Tomt ($ current_class); // Hvis dette er en toppnivåkobling og ikke den nåværende eller forfedre for gjeldende menyelement - stopp her. hvis (0 == $ dybde &&! $ ancestor_of_current) returnere; foreldre :: display_element ($ element, & $ children_elements, $ max_depth, $ depth, $ args, & $ output);
Vi utvider nå start_lvl
og end_lvl
funksjoner. Disse er ansvarlige for å sende ut HTML som bryter et nivå (i dette tilfellet
tags). Hvis vi er på toppnivå, ønsker vi ikke å vise disse kodene (etter alt vil innholdet ikke bli vist).
// Ikke vikle toppnivåfunksjonen start_lvl (& $ output, $ depth = 0, $ args = array ()) hvis (0 == $ dybde) tilbake; foreldre :: start_lvl (& $ utgang, $ dybde, $ args); funksjon end_lvl (& $ output, $ depth = 0, $ args = array ()) hvis (0 == $ dybde) tilbake; foreldre :: end_lvl (& $ output, $ depth, $ args);
Den klassen i sin helhet:
klasse SH_Child_Only_Walker utvider Walker_Nav_Menu // Ikke start toppnivå funksjonen start_lvl (& $ output, $ depth = 0, $ args = array ()) hvis (0 == $ dybde) tilbake; foreldre :: start_lvl (& $ utgang, $ dybde, $ args); // Ikke avslutt toppnivåfunksjonen end_lvl (& $ output, $ depth = 0, $ args = array ()) hvis (0 == $ dybde) tilbake; foreldre :: end_lvl (& $ output, $ depth, $ args); // Ikke skriv ut elementene i toppnivået start_el (& $ output, $ item, $ deep = 0, $ args = array ()) hvis (0 == $ dybde) tilbake; foreldre :: start_el (& $ utgang, $ element, $ dybde, $ args); funksjon end_el (& $ output, $ item, $ depth = 0, $ args = array ()) hvis (0 == $ dybde) tilbake; foreldre :: end_el (& $ output, $ item, $ depth, $ args); // Bare følg ned en grenfunksjon display_element ($ element, & $ children_elements, $ max_depth, $ depth = 0, $ args og $ output) // Sjekk om elementet som en 'nåværende element'-klasse $ current_element_markers = array ('nåværende meny-element', 'nåværende meny-forelder', 'nåværende meny-forfader'); $ current_class = array_intersect ($ current_element_markers, $ element-> classes); // Hvis elementet har en 'nåværende' klasse, er det en forfedre av det nåværende elementet $ ancestor_of_current =! Tomt ($ current_class); // Hvis dette er en toppnivåkobling og ikke den nåværende eller forfedre for gjeldende menyelement - stopp her. hvis (0 == $ dybde &&! $ ancestor_of_current) returnere foreldre :: display_element ($ element, & $ children_elements, $ max_depth, $ depth, $ args, & $ output);
Når du forstår hvordan walker-klassen fungerer, kan du utvide den (eller WordPress 'eksisterende utvidelser) for å endre hvordan dine hierarkiske data vises. For eksempel kan du: