Le voci di menu, le pagine e le tassonomie (gerarchiche) sono tutti esempi di dati con una struttura ad albero: i termini possono avere genitori, figli e fratelli. Di solito vorremmo riflettere questa struttura nel markup HTML. Per visualizzare un menu, ad esempio, vogliamo che l'HTML sia una lista di link di "livello superiore", con liste annidate dei loro figli, che a loro volta contengono liste annidate dei loro figli, e così via. Questo tutorial ti guiderà attraverso una classe di WordPress che rende estremamente semplice la produzione di questo mark-up.
La classe walker è una classe astratta progettata per aiutare a superare e visualizzare elementi che hanno una struttura gerarchica (o simile a un albero). In realtà non "fa" (nel senso di generare HTML) nulla. Traccia semplicemente ogni ramo del tuo albero: deve essere esteso da altre classi che gli dicono cosa fare per ogni elemento che incontra. WordPress fornisce le proprie classi di estensione, come ad esempio:
Walker_Nav_Menu
- per visualizzare l'HTML per i menu di navigazioneWalker_Page
- per visualizzare un elenco di pagineWalker_Category
- per visualizzare un elenco di termini di tassonomia.Ognuna di queste classi estende la classe Walker semplicemente dettando ciò che la classe emette ad ogni elemento e livello dell'albero. Per demistificare questa classe, esamineremo i suoi metodi principali e un paio di esempi su come usarlo. La classe stessa può essere trovata qui.
Camminare
camminare ($ elementi, $ max_depth)
La classe walker viene avviata con il metodo walk ed è questo metodo che restituisce l'HTML una volta generato. Accetta due argomenti:
$ max_depth
- imposta il numero di generazioni che esploriamo$ args
. Questo viene quindi passato ad altri metodi nella classeIl metodo walk individua gli elementi di "livello superiore", quelli senza genitori, e li colloca in un unico array. Il resto, i bambini, sono collocati in un secondo array in cui la chiave è l'ID del suo genitore (è un array bidimensionale poiché un genitore può avere più figli):
$ children_elements = array ('1' => array () // Matrice di elementi corrispondenti a figli di 1, '4' => array () // Matrice di elementi corrispondenti a figli di 4);
Quindi scorre a turno ciascuno degli elementi padre e applica il metodo display_element
.
Display_Element
display_element ($ element, & $ children_elements, $ max_depth, $ depth = 0, $ args e $ output)
Come suggerisce il nome display_element
è responsabile della visualizzazione di un elemento nel nostro albero. In effetti, chiama diverse funzioni per farlo. Queste funzioni vengono lasciate volutamente in bianco nella classe Walker - ed è queste che vengono alterate nelle classi di estensione, in quanto determinano il codice HTML restituito. Questi includono:
start_lvl
- una funzione per restituire l'HTML per l'inizio di un nuovo livello. Nel caso delle liste, questo sarebbe l'inizio di una nuova 'sotto-lista', e quindi sarebbe responsabile della restituzione del
etichettaend_lvl
- chiamato quando abbiamo finito un livello. Nell'esempio del menu di navigazione, questa funzione è responsabile della terminazione della sottocodice con un tag di chiusura
start_el
- la funzione responsabile della visualizzazione dell'elemento corrente su cui ci troviamo. Nel caso dei menu, questo significa
tag e il link dell'articolo.end_el
- la funzione chiamata dopo un elemento e tutti i suoi figli sono stati visualizzati. Per il nostro esempio di menu questo significa restituire una chiusura
Quindi cosa fa display_element
davvero? In realtà è dove si svolge tutta la magia della lezione Walker. Per prima cosa diamo un'occhiata a quali argomenti è stato fornito:
$ elemento
- questo è l'elemento che stiamo attualmente sul nostro albero$ children_elements
- una serie di tutti elementi figlio (non solo figli dell'elemento di cui sopra). Questa è la seconda matrice formata nel camminare
metodo e le chiavi sono gli ID del genitore.$ max_depth
- fino a che punto siamo in grado di esplorare$ profondità
- quanto siamo giù attualmente$ args
- argomenti facoltativi (menzionati in precedenza)$ uscita
- L'HTML finora. Questo è aggiunto a come esploriamo più dell'albero. Il display_element
metodo prime chiamate start_el
che è responsabile della visualizzazione dell'elemento. Esattamente come ciò dipende dal contesto. Per un menu a discesa potrebbe essere o per un menu di navigazione che potrebbe
. Si noti che non esiste ancora un tag di chiusura. Se questo elemento ha figli, dobbiamo prima visualizzarli in modo tale da essere annidati all'interno di questo elemento ...
Quindi dopo controlla se l'elemento corrente su cui ci troviamo ha figli e non abbiamo raggiunto la profondità massima. Se è così, esploriamo ciascuno dei bambini a sua volta, chiamando display_element
per ognuno di essi (con l'argomento profondità incrementato di uno). In questo modo il display_element
si chiama in modo ricorsivo fino a raggiungere il fondo.
Supponiamo di aver raggiunto il "fondo" (un elemento senza figli o la profondità massima), quindi chiama end_el
che aggiunge il tag di chiusura. C'è l'istanza attuale di display_element
finisce e torniamo al genitore che si applica display_element
al prossimo figlio, finché non avremo elaborato ciascuno dei suoi figli. Quando il genitore non ha più figli rimasti, risaliamo l'albero, e così via fino a quando ogni ramo è esplorato. Confuso? È un diagramma che spero chiarisca le cose:
L'uso della classe Walker rende molto semplice la visualizzazione di dati gerarchici personalizzati. Supponiamo di avere una serie di oggetti, con 'etichetta
','parent_id
' e 'object_id
'proprietà di cui si desidera visualizzare un elenco. Questo può ora essere facilmente realizzato con una classe molto semplice:
Nota: La classe estesa è responsabile per l'impostazione dove trovare l'ID di un elemento e quello del suo genitore.
class Walker_Simple_Example estende Walker // Imposta le proprietà dell'elemento che danno l'ID dell'elemento corrente e il suo genitore var $ db_fields = array ('parent' => 'parent_id', 'id' => 'object_id'); // Visualizza l'inizio di un livello. Per esempio '
È possibile estendere le classi Walker per modificare il contenuto visualizzato, modificare l'HTML generato o addirittura impedire la visualizzazione di determinati rami. Funzioni come:
wp_nav_menu
wp_list_pages
wp_list_categories
Fornisci un'opzione per specificare la tua classe Walker personalizzata, consentendoti di modificare il loro aspetto con relativa facilità, specificando la tua classe di walker personalizzata. In molti casi è più semplice estendere un'estensione Walker appropriata, piuttosto che la stessa classe Walker.
Supponiamo di voler avere un menu secondario (secondario) correlato al tuo menu principale. Questo può assumere la forma di link che si trovano appena sotto il menu principale o in una barra laterale che mostra solo gli elementi del menu 'discendente' della corrente 'pagina di livello superiore'. Ad esempio dal diagramma sopra, se siamo nelle sotto-pagine 'Archive', 'Author' o 'News', vorremmo mostrare tutti i link sotto 'Archive'. Da Walker_Nav_Menu
fa la maggior parte di ciò che vogliamo, estenderemo quella classe piuttosto che la classe Walker. Questo ci risparmia molti sforzi, dal momento che Walker_Nav_Menu
aggiunge le classi appropriate ('attuale
','current-antenato
'ecc.) ai collegamenti pertinenti. Estenderemo il Walker_Nav_Menu
Walker Class per modificare leggermente la logica e impedirgli di visualizzare link di livello superiore o discendenti delle pagine 'non-root'.
Prima di tutto, nei file del modello, useremo il wp_nav_menu ()
funzione due volte, che punta allo stesso posizione del tema (Lo chiamerò 'primario
'). Se non si dispone già di una posizione tematica registrata, leggere questo articolo. Indipendentemente dal luogo in cui si sta utilizzando il tema, è necessario salvare un menu in quella posizione. Mostreremo questo menu due volte. Innanzitutto, dovunque desideri che appaia il tuo menu 'di primo livello':
wp_nav_menu (array ('theme_location' => 'primary', 'depth' => 1));
Poi di nuovo, con un deambulatore personalizzato, per visualizzare solo le pagine figlio (rilevanti).
wp_nav_menu (array ('theme_location' => 'primary', 'walker' => new SH_Child_Only_Walker (), 'depth' => 0));
Prima di tutto non vogliamo mostrare i genitori di alto livello. Ricordiamo che la funzione responsabile per l'apertura tag e il link è
start_el
e la funzione responsabile della chiusura il tag è
end_el
. Controlliamo semplicemente se siamo a livello dei genitori. Se lo siamo, non facciamo nulla. Altrimenti, continuiamo 'normalmente' e chiamiamo la funzione dal Walker_Nav_Menu
classe.
// Non stampare la funzione di elementi di livello superiore start_el (& $ output, $ item, $ depth = 0, $ args = array ()) if (0 == $ depth) return; genitore :: start_el (& $ output, $ item, $ depth, $ args); function end_el (& $ output, $ item, $ depth = 0, $ args = array ()) if (0 == $ depth) return; parent :: end_el (& $ output, $ item, $ depth, $ args);
Estendiamo il display_element
. Questa funzione è responsabile per viaggiare lungo i rami. Vogliamo interromperlo se ci troviamo al livello più alto e non al collegamento root corrente. Per verificare se il ramo su cui ci troviamo sia 'corrente', controlliamo se l'elemento ha una delle seguenti classi: 'corrente-menu-item
','corrente-menu-genitore
','corrente-menu-antenato
'.
// Segui solo una funzione branch display_element ($ element, & $ children_elements, $ max_depth, $ depth = 0, $ args e $ output) // Verifica se elemento come una classe 'elemento corrente' $ current_element_markers = array ( 'current-menu-item', 'current-menu-parent', 'current-menu-antenato'); $ current_class = array_intersect ($ current_element_markers, $ element-> classes); // Se l'elemento ha una classe 'corrente', è un antenato dell'elemento corrente $ ancestor_of_current =! Empty ($ current_class); // Se si tratta di un collegamento di livello superiore e non di quello corrente o antenato della voce di menu corrente, fermati qui. se (0 == $ depth &&! $ ancestor_of_current) ritorno; parent :: display_element ($ element, & $ children_elements, $ max_depth, $ depth, $ args e $ output);
Ora estendiamo il start_lvl
e end_lvl
funzioni. Questi sono responsabili dell'output dell'HTML che racchiude un livello (in questo caso il
tag). Se siamo al livello più alto non vogliamo mostrare questi tag (dopo che tutti i contenuti non saranno mostrati).
// Non avvolgere la funzione di primo livello start_lvl (& $ output, $ depth = 0, $ args = array ()) if (0 == $ depth) return; parent :: start_lvl (& $ output, $ depth, $ args); funzione end_lvl (& $ output, $ depth = 0, $ args = array ()) if (0 == $ depth) return; parent :: end_lvl (& $ output, $ depth, $ args);
Quella classe per intero:
la classe SH_Child_Only_Walker estende Walker_Nav_Menu // Non avvia la funzione di primo livello start_lvl (& $ output, $ depth = 0, $ args = array ()) if (0 == $ depth) return; parent :: start_lvl (& $ output, $ depth, $ args); // Non terminare la funzione di livello superiore end_lvl (& $ output, $ depth = 0, $ args = array ()) if (0 == $ depth) return; parent :: end_lvl (& $ output, $ depth, $ args); // Non stampare la funzione di elementi di livello superiore start_el (& $ output, $ item, $ depth = 0, $ args = array ()) if (0 == $ depth) return; genitore :: start_el (& $ output, $ item, $ depth, $ args); function end_el (& $ output, $ item, $ depth = 0, $ args = array ()) if (0 == $ depth) return; parent :: end_el (& $ output, $ item, $ depth, $ args); // Segui solo una funzione branch display_element ($ element, & $ children_elements, $ max_depth, $ depth = 0, $ args e $ output) // Verifica se elemento come una classe 'elemento corrente' $ current_element_markers = array ('current-menu-item', 'current-menu-parent', 'current-menu-ancestor'); $ current_class = array_intersect ($ current_element_markers, $ element-> classes); // Se l'elemento ha una classe 'corrente', è un antenato dell'elemento corrente $ ancestor_of_current =! Empty ($ current_class); // Se si tratta di un collegamento di livello superiore e non di quello corrente o antenato della voce di menu corrente, fermati qui. if (0 == $ depth &&! $ ancestor_of_current) restituisce parent :: display_element ($ element, & $ children_elements, $ max_depth, $ depth, $ args e $ output);
Una volta compreso come funziona la classe Walker, puoi estenderla (o le estensioni esistenti di WordPress) per modificare la modalità di visualizzazione dei dati gerarchici. Ad esempio puoi: