Menu-items, pagina's en (hiërarchische) taxonomieën zijn allemaal voorbeelden van gegevens met een boomachtige structuur: termen kunnen ouders, kinderen en broers en zussen hebben. Meestal willen we deze structuur weergeven in de HTML-markup. Voor het weergeven van een menu willen we bijvoorbeeld dat de HTML een lijst met 'topniveau'-links is, met geneste lijsten van hun kinderen, die zelf geneste lijsten van hun kinderen bevatten, enzovoort. Deze tutorial begeleidt je door een les in WordPress biedt die het maken van deze opmaak extreem eenvoudig maakt.
De Walker-klasse is een abstracte klasse die is ontworpen om te helpen bij het doorkruisen en weergeven van elementen die een hiërarchische (of boomachtige) structuur hebben. Het 'doet' het niet (in de betekenis van het genereren van HTML) iets. Het traceert eenvoudig elke tak van je boom: het moet uitgebreid worden door andere klassen die het vertellen wat te doen voor elk element dat het tegenkomt. WordPress biedt zijn eigen uitbreidingsklassen, zoals:
Walker_Nav_Menu
- voor het weergeven van de HTML voor navigatiemenu'sWalker_Page
- voor het weergeven van een lijst met pagina'sWalker_Category
- voor het weergeven van een lijst met taxonomietermen.Elk van deze klassen breidt de Walker-klasse uit door simpelweg te dicteren wat de klasse uitvoert op elk element en niveau van de boom. Om deze klasse te ontmystificeren, zullen we kijken naar de belangrijkste methoden en een paar voorbeelden van hoe deze te gebruiken. De klas zelf is hier te vinden.
Lopen
lopen ($ elementen, $ max_depth)
De Walker-klasse wordt gestart met de methode Walk en het is deze methode die de HTML retourneert zodra deze is gegenereerd. Het accepteert twee argumenten:
$ max_depth
- bepaalt hoeveel generaties we onderzoeken$ args
. Dit wordt vervolgens doorgegeven aan andere methoden in de klasDe wandelmethode selecteert de elementen op het hoogste niveau - die zonder ouders - en plaatst ze in één array. De rest, de kinderen, worden in een tweede array geplaatst waar de sleutel de ID van de bovenliggende array is (het is een tweedimensionale array aangezien een ouder meerdere kinderen kan hebben):
$ children_elements = array ('1' => array () // Array van elementen die overeenkomen met kinderen van 1, '4' => array () // Array van elementen die overeenkomen met kinderen van 4);
Vervolgens worden de bovenliggende elementen om beurten doorlopen en wordt de methode toegepast display_element
.
Display_Element
display_element ($ element, & $ children_elements, $ max_depth, $ depth = 0, $ args, & $ output)
Zoals de naam al doet vermoeden display_element
is verantwoordelijk voor het weergeven van een element in onze stamboom. In feite roept het verschillende functies om dit te doen. Deze functies zijn bewust leeg gelaten in de klasse Walker - en deze zijn gewijzigd in de verlengende klassen, omdat ze de daadwerkelijke HTML-code bepalen die wordt geretourneerd. Waaronder:
start_lvl
- een functie om de HTML terug te sturen naar het begin van een nieuw niveau. In het geval van lijsten zou dit het begin zijn van een nieuwe 'sublijst', en zou dus verantwoordelijk zijn voor het retourneren van de
labelend_lvl
- gebeld wanneer we een level hebben voltooid. In het voorbeeld van het navigatiemenu is deze functie verantwoordelijk voor het beëindigen van de sublijst met een afsluitende lijsttag
start_el
- de functie die verantwoordelijk is voor het weergeven van het huidige element waar we op staan. In het geval van menu's betekent dit het
tag en de link van het item.end_el
- de functie die is genoemd naar een element en al zijn kinderen zijn weergegeven. Voor ons menu betekent dit het retourneren van een afsluiting
Dus wat doet het display_element
eigenlijk doen? Het is eigenlijk waar alle magie van de Walker-klasse plaatsvindt. Laten we eerst eens kijken naar de argumenten die het heeft gekregen:
$ element
- dit is het element dat we momenteel in onze boom hebben$ children_elements
- een reeks van allemaal onderliggende elementen (niet alleen kinderen van het element waarnaar hierboven wordt verwezen). Dit is de tweede reeks gevormd in de lopen
methode en de sleutels zijn de ID's van de ouder.$ max_depth
- hoe diep we mogen verkennen$ diepte
- hoe diep we op dit moment zijn$ args
- optionele argumenten (eerder genoemd)$ uitgang
- De HTML tot nu toe. Dit wordt toegevoegd als we meer van de boom verkennen. De display_element
methode eerste oproepen start_el
welke verantwoordelijk is voor het weergeven van het element. Precies hoe dat gebeurt, hangt af van de context. Voor een vervolgkeuzemenu is dat mogelijk of voor een navigatiemenu dat kan
. Merk op dat er nog geen sluitingscode is. Als dit element kinderen heeft, moeten we ze eerst weergeven zodat ze zijn genest in dit item ...
Dus vervolgens wordt gecontroleerd of het huidige element waar we aan toe zijn kinderen heeft en dat we de maximale diepte niet hebben bereikt. Als dat zo is, verkennen we elk van de kinderen om beurten, door te bellen display_element
voor elk van hen (met het dieptewoord met één opgehoogd). Op deze manier de display_element
herhaalt zich recursief totdat we de bodem bereiken.
Stel dat we de 'onderkant' hebben bereikt (een element zonder kinderen of de maximale diepte), dan roept het end_el
die de afsluitende tag toevoegt. Daar is de huidige instantie van display_element
eindigt en we gaan terug naar de ouder die solliciteert display_element
naar het volgende kind, totdat we elk van zijn kinderen hebben verwerkt. Als de ouder geen kinderen meer heeft, gaan we terug de boom in, enzovoort, totdat elke tak wordt verkend. Verward? Hij is een diagram waarvan ik hoop dat het dingen zal verhelderen:
Het gebruik van de Walker-klasse maakt het tonen van aangepaste hiërarchische gegevens erg eenvoudig. Stel dat je een reeks objecten hebt, met 'label
','ouder ID
'en'object_id
'eigenschappen waarvan u een lijst wilt weergeven. Dit kan nu eenvoudig worden bereikt met een heel eenvoudige klasse:
Notitie: De uitbreidingsklasse is verantwoordelijk voor het instellen van de ID van een element en die van het bovenliggende element.
class Walker_Simple_Example verlengt Walker // Stel de eigenschappen in van het element dat de ID van het huidige item en het bijbehorende parent oplevert var $ db_fields = array ('parent' => 'parent_id', 'id' => 'object_id'); // Geeft het begin van een niveau weer. Bijv.
U kunt de rollatorklassen uitbreiden om te wijzigen welke inhoud wordt weergegeven, de gegenereerde HTML wijzigen of zelfs voorkomen dat bepaalde branches worden getoond. Functies zoals:
wp_nav_menu
wp_list_pages
wp_list_categories
Geef een optie om uw eigen aangepaste Walker-klasse op te geven, zodat u hun uiterlijk relatief eenvoudig kunt wijzigen door uw eigen aangepaste rollatorklasse op te geven. In veel gevallen is het eigenlijk gemakkelijker om een geschikte walker-extensie uit te breiden, in plaats van de Walker-klasse zelf.
Stel dat u een secundair (sub) menu wilt hebben dat gerelateerd is aan uw primaire menu. Dit kan de vorm aannemen van koppelingen die zich net onder uw hoofdmenu bevinden of in een zijbalk die alleen de 'nakomende' menu-items van de huidige 'hoofdpagina' laat zien. Als een voorbeeld van het bovenstaande diagram, willen we dat als we op de subpagina's 'Archief', 'Auteur' of 'Nieuws' staan, we alle links onder 'Archief' willen laten zien. Sinds Walker_Nav_Menu
doet het meeste van wat we willen, we zullen die klasse uitbreiden in plaats van de Walker-klas. Dit scheelt ons veel moeite, sinds de Walker_Nav_Menu
voegt de juiste klassen toe ('stroom
','stroomvoerende voorouder
'etc) naar de relevante links. We zullen de Walker_Nav_Menu
walker-klasse om de logica enigszins te wijzigen en te voorkomen dat deze koppelingen op het hoogste niveau of een van de afstammelingen van de 'niet-root'-pagina's weergeeft.
Allereerst gebruiken we in uw sjabloonbestanden de wp_nav_menu ()
functioneer tweemaal, wijzend naar hetzelfde thema locatie (Ik zal het noemen 'primair
'). Als u nog geen themapositie hebt geregistreerd, moet u dit artikel lezen. Welke themapositie u ook gebruikt, u moet een menu op die locatie opslaan. We zullen dit menu twee keer weergeven. Ten eerste, waar je ook wilt dat je 'hoofdmenu' verschijnt:
wp_nav_menu (array ('theme_location' => 'primary', 'depth' => 1));
Nogmaals, met een aangepaste rollator, om alleen de (relevante) onderliggende pagina's weer te geven.
wp_nav_menu (array ('theme_location' => 'primary', 'walker' => nieuw SH_Child_Only_Walker (), 'depth' => 0));
Allereerst willen we de ouders op het hoogste niveau niet weergeven. Bedenk dat de functie verantwoordelijk is voor de opening tag en de link is
start_el
en de functie die verantwoordelijk is voor het sluiten tag is
end_el
. We controleren eenvoudig of we op het bovenliggende niveau zijn. Als dat zo is, doen we niets. Anders gaan we verder 'als normaal' en noemen we de functie van de Walker_Nav_Menu
klasse.
// Druk geen elementen op het hoogste niveau af start_el (& $ output, $ item, $ depth = 0, $ args = array ()) if (0 == $ depth) return; parent :: start_el (& $ output, $ item, $ depth, $ args); functie end_el (& $ output, $ item, $ depth = 0, $ args = array ()) if (0 == $ depth) return; parent :: end_el (& $ output, $ item, $ depth, $ args);
We verlengen de display_element
. Deze functie is verantwoordelijk voor het afdalen van de takken. We willen het in zijn tracks stoppen als we ons op het hoogste niveau bevinden en niet op de huidige root-link. Om te controleren of de branch waar we ons bevinden 'current' is, controleren we of het item een van de volgende klassen heeft: 'huidige menubestanddeel
','current-menu-parent
','current-menu-voorouder
'.
// Alleen één branch-functie display_element volgen ($ element, & $ children_elements, $ max_depth, $ depth = 0, $ args, & $ output) // Controleer of element als een 'huidig element'-klasse $ current_element_markers = array ( 'current-menu-item', 'current-menu-parent', 'current-menu-ancestor'); $ current_class = array_intersect ($ current_element_markers, $ element-> classes); // Als element een 'huidige' klasse heeft, is dit een voorloper van het huidige element $ ancestor_of_current =! Empty ($ current_class); // Als dit een koppeling op het hoogste niveau is en niet de huidige of voorloper van het huidige menu-item - stop hier. als (0 == $ depth &&! $ ancestor_of_current) retour komt; parent :: display_element ($ element, & $ children_elements, $ max_depth, $ depth, $ args, & $ output);
We breiden nu het start_lvl
en end_lvl
functies. Deze zijn verantwoordelijk voor het uitvoeren van de HTML die een niveau omhult (in dit geval de
-tags). Als we op het hoogste niveau zitten, willen we deze tags niet weergeven (de inhoud wordt immers niet getoond).
// Wikkel de functie op het hoogste niveau niet in start_lvl (& $ output, $ depth = 0, $ args = array ()) if (0 == $ depth) return; parent :: start_lvl (& $ output, $ depth, $ args); function end_lvl (& $ output, $ depth = 0, $ args = array ()) if (0 == $ depth) return; parent :: end_lvl (& $ output, $ depth, $ args);
Die klas volledig:
class SH_Child_Only_Walker verlengt Walker_Nav_Menu // Start de functie op het hoogste niveau niet start_lvl (& $ output, $ depth = 0, $ args = array ()) if (0 == $ depth) return; parent :: start_lvl (& $ output, $ depth, $ args); // Sluit de functie op het hoogste niveau niet af end_lvl (& $ output, $ depth = 0, $ args = array ()) if (0 == $ depth) return; parent :: end_lvl (& $ output, $ depth, $ args); // Druk geen elementen op het hoogste niveau af start_el (& $ output, $ item, $ depth = 0, $ args = array ()) if (0 == $ depth) return; parent :: start_el (& $ output, $ item, $ depth, $ args); functie end_el (& $ output, $ item, $ depth = 0, $ args = array ()) if (0 == $ depth) return; parent :: end_el (& $ output, $ item, $ depth, $ args); // Alleen één vertakkingsfunctie weergeven_element ($ element, & $ children_elements, $ max_depth, $ depth = 0, $ args, $ uitvoer) // Controleer of element als een 'huidig element'-klasse $ current_element_markers = array ('current-menu-item', 'current-menu-parent', 'current-menu-ancestor'); $ current_class = array_intersect ($ current_element_markers, $ element-> classes); // Als element een 'huidige' klasse heeft, is dit een voorloper van het huidige element $ ancestor_of_current =! Empty ($ current_class); // Als dit een koppeling op het hoogste niveau is en niet de huidige of voorloper van het huidige menu-item - stop hier. if (0 == $ depth &&! $ ancestor_of_current) return parent :: display_element ($ element, & $ children_elements, $ max_depth, $ depth, $ args, & $ output);
Als u eenmaal begrijpt hoe de Walker-klasse werkt, kunt u deze uitbreiden (of bestaande extensies van WordPress) om de manier waarop uw hiërarchische gegevens worden weergegeven, te wijzigen. U kunt bijvoorbeeld: