Familiarizzare con la classe Walker di WordPress

Pubblicato: 2020-11-27

Se non hai familiarità con la Walker Class preparati a rimanere stupito da quanto può essere utile per il tuo lavoro. La WordPress Walker Class è stata implementata in WordPress 2.1 per fornire agli sviluppatori un mezzo per attraversare strutture di dati simili ad alberi allo scopo di eseguire il rendering di HTML. In questo articolo studieremo come funziona il parametro walker e come personalizzare gli output in menu, categorie e commenti.

Muoviamoci!

Panoramica della classe Walker

In WordPress, vediamo spesso oggetti che hanno una struttura gerarchica come menu di navigazione, elenchi di categorie o elenchi di commenti

Come forse già saprai, nel caso di una struttura ad albero di dati, alcuni elementi sono i genitori e altri sono i loro figli. "Post Sottocategoria 1" è un elemento secondario di "Post Categoria 1", una risposta a un commento è un commento figlio al commento stesso e "Servizio 1" è una voce di menu figlio dell'elemento "Servizi".

Il Walker è chiamato così in quanto semplicemente "cammina" attraverso ogni oggetto o array associativo ed esegue una funzione su ciascun nodo. Ciò che vorremmo ottenere con questo è la capacità di elencare i collegamenti di "livello superiore", con i loro elementi "figli" in modi diversi a seconda delle nostre esigenze specifiche.

In altre parole, WordPress ti offre una struttura <ul> <li> standard e puoi personalizzarne gli argomenti, ma, estendendo il Walker puoi personalizzare la struttura stessa modificandone il contenuto HTML.

Il file principale relativo alla Walker Class è wp-includes/class-wp-walker.php e governa tutti i tipi di dati ad albero che abbiamo elencato in precedenza.

Poiché è una classe PHP astratta, per generare qualsiasi HTML, deve essere estesa dallo sviluppatore che definirà una versione personalizzata delle sue proprietà e metodi. Quindi studiamo le classi figlio nel file class-wp-walker.php una per una.

Classi per bambini

$tree_type è una variabile facoltativa che arriva in un tipo o in una matrice di tipi e definisce ciò che la classe gestisce.

 public $tree_type = array( 'post_type', 'taxonomy', 'custom' );

$db_fields è una variabile obbligatoria e definisce quali campi del database utilizzare. Questa proprietà è un array con due chiavi: 'parent' e 'id' i cui valori sono i nomi delle proprietà dell'oggetto che contengono rispettivamente l'id genitore e l'id elemento.

 public $db_fields = array( 'parent' => 'menu_item_parent', 'id' => 'db_id', );

Anche la proprietà $max_pages è facoltativa e il suo ruolo è quello di specificare il numero massimo di pagine percorse dal paged walker.

 public $max_pages = 1;

$has_children è in realtà autoesplicativo e ha un valore vero o falso a seconda che l'elemento corrente abbia figli.

 public $has_children;

Il metodo start_lvl viene eseguito sulla radice di un nuovo oggetto ad albero e prende gli argomenti $output, $depth e $args.

 public function start_lvl( &$output, $depth = 0, $args = array() ) {}

L'argomento $output aggiunge contenuto aggiuntivo, $depth specifica la profondità dell'elemento e $args è una matrice di argomenti aggiuntivi.

Il metodo end_lvl chiude qualsiasi tag precedentemente aperto dal metodo start_lvl.

 public function end_lvl( &$output, $depth = 0, $args = array() ) {}

Il start_el (Start Element) viene utilizzato per visualizzare il tag HTML di apertura per l'elemento corrente. Nel caso di un menu, ad esempio, di solito è un tag <li>.

 public function start_el( &$output, $object, $depth = 0, $args = array(), $current_object_id = 0 ) {}

La funzione end_el viene chiamata dopo che Walker ha passato un elemento con tutti i suoi figli e ha restituito un tag di chiusura.

 public function end_el( &$output, $object, $depth = 0, $args = array() ) {}

Il display_element visualizza effettivamente gli elementi dell'oggetto albero. Chiama start_el , start_lvl , display_element , end_lvl , end_el in questo ordine. Ora diamo un'occhiata alle sue argomentazioni.

  • $elemento : l'elemento corrente
  • $bambini_elementi : tutti gli elementi figlio dell'oggetto albero
  • $max_depth : il limite massimo di profondità che possiamo esplorare
  • $depth : Il livello in cui ci troviamo attualmente
  • $args : argomenti opzionali aggiuntivi
  • $output : l'output HTML corrente.

Dimostreremo ora un esempio per ogni tipo di dati utilizzando un'installazione di WordPress con il tema Twenty Twenty attivato.

Personalizzazione di una struttura di menu

La funzione wp_nav_menu() che WordPress utilizza per visualizzare i menu è inclusa nel file wp-includes/nav-menu-template.php . In questo file, WordPress richiede anche la classe Walker_Nav_Menu attorno alla riga 605.

 function walk_nav_menu_tree( $items, $depth, $r ) { $walker = ( empty( $r->walker ) ) ? new Walker_Nav_Menu : $r->walker; return $walker->walk( $items, $depth, $r ); }

La classe Walker_Nav_Menu è definita all'interno del file wp-includes/class-walker-nav-menu.php ed è fondamentalmente tutto il contenuto del file.

Per visualizzare l'output del menu, il codice WordPress utilizza le proprietà e i metodi della Classe Walker_Nav_Menu descritti all'interno di questo file.

Ad esempio, risolviamo un problema ben noto che molti sviluppatori devono affrontare, ovvero cambiare l'elemento per le voci del menu principale con un link personalizzato vuoto ('#') per impedire ai visitatori di fare clic su di esse.

Per permetterci di confrontare i nostri risultati, creeremo prima un clone del menu principale semplicemente aggiungendo il codice sottostante header.php subito dopo l'inizio dell'elemento <header> .

 <header class="header-footer-group" role="banner"> <?php wp_nav_menu( array( 'menu_class' => 'primary-menu reset-list-style' ) ); ?>

Quello che abbiamo effettivamente fatto qui è stato rigenerare il menu principale ed ereditare la sua funzionalità a discesa e CSS aggiungendo anche le sue classi primary-menu reset-list-style al nuovo menu.

Ora nel nostro file functions.php creeremo una classe che estende la classe Walker_Nav_Menu. Dal momento che vogliamo cambiare il tipo di elemento, sovrascriveremo il metodo start_el .

 if ( !class_exists('My_Custom_Nav_Walker') ) { class My_Custom_Nav_Walker extends Walker_Nav_Menu { function start_el(&$output, $item, $depth=0, $args=[], $id=0) { $output .= "<li class='" . implode(" ", $item->classes) . "'>"; if ($item->url && $item->url != '#') { $output .= '<a href="' . $item->url . '">'; } else { $output .= '<span>'; } $output .= $item->title; if ($item->url && $item->url != '#') { $output .= '</a>'; } else { $output .= '</span>'; } } } }

Quindi abbiamo racchiuso ogni elemento normalmente con un tag <li> e poi, con l'uso dell'istruzione if, abbiamo aggiunto un intervallo quando un collegamento è "#" e un tag <a> per il resto.

Per applicarlo al nostro menu torniamo al codice menu che abbiamo aggiunto in precedenza e specifichiamo il parametro walker:

 wp_nav_menu( array( 'walker' => new My_Custom_Nav_Walker, 'menu_class' => 'primary-menu reset-list-style' ) );

Ora il risultato dovrebbe assomigliare a questo:

Se ora passi il mouse sopra "Servizi" nella voce di menu, non apparirà il cursore della mano e nemmeno questa voce di menu è selezionabile. Tuttavia, il sottomenu a discesa verrà comunque visualizzato correttamente.

Personalizzazione delle categorie

Per prima cosa vai nell'area di amministrazione e crea alcune categorie e sottocategorie di post in modo da avere un albero delle categorie per la dimostrazione.

Successivamente genereremo un elenco di categorie aggiungendo questo codice da qualche parte in header.php . Puoi metterlo dopo l'inizio dell'elemento di intestazione come in precedenza.

 <header class="header-footer-group" role="banner"> <?php wp_list_categories( array('hide_empty' => FALSE) ); ?>

La funzione è una funzione integrata di WordPress che genera un output HTML di un albero di categorie. Per impostazione predefinita mostra solo le categorie che contengono post, ecco perché abbiamo usato l'opzione hide_empty per visualizzare anche le categorie vuote e vedere l'intera gerarchia ai fini di questo esempio.

Come in precedenza, possiamo creare una classe personalizzata in functions.php per estendere la classe Walker_Category predefinita descritta nel file wp-includes/class-walker-category.php e applicare le nostre modifiche. Ad esempio, aggiungeremo alcune icone prima dei nomi delle categorie aggiungendo questo codice:

 if ( !class_exists('My_Category_tree_Walker') ) { class My_Category_tree_Walker extends Walker_Category { function start_el(&$output, $item, $depth=0, $args=array(),$current_object_id = 0) { $output.= '<li><a href="'.home_url('category/'.$item->slug).'"> <img src="http://path/to/mages/'.($item->slug).'.jpg"> '.esc_attr($item->name); } } }

Affinché ciò funzioni, dovrai ovviamente preparare immagini adatte e salvarle nella cartella definita. Queste immagini dovrebbero seguire un formato di nome specifico che in questo esempio sarebbe "post-category-1", "post-subcategory-1", "post-category-3.jpg" ecc.

Personalizzazione dei commenti

L'aggiornamento del menu e dell'elenco delle categorie è di gran lunga i motivi più comuni per cui potresti personalizzare una classe Walker, ma a volte devi implementare la stessa tecnica anche per i commenti. Se, ad esempio, vuoi modificare le meta informazioni accanto all'immagine Gravatar nella sezione commenti, possiamo farlo facilmente estendendo la classe Walker_Comment che si trova nel file wp-includes/class-walker-comment.php.

Nel file functions.php aggiungi questo codice

 if ( !class_exists('My_Comment_Walker') ) { class My_Comment_Walker extends Walker_Comment { protected function html5_comment( $comment, $depth, $args ) { $tag = ( 'div' === $args['style'] ) ? 'div' : 'li'; ?> <<?php echo $tag; ?> <?php comment_class( $this->has_children ? 'parent' : '', $comment ); ?>> <article class="comment-body"> <footer class="comment-meta"> <div class="comment-author vcard"> <?php if ( 0 != $args['avatar_size'] ) echo get_avatar( $comment, $args['avatar_size'] ); ?> <?php printf( __( '%s <span class="says">says:</span>' ), sprintf( '<span class="fn">%s</span>', get_comment_author_link( $comment ) ) ); ?> </div><!-- .comment-author --> <div class="comment-metadata"> <?php $user_id=$comment->user_id; ?> <p class="commenter-bio"><?php the_author_meta('description',$user_id); ?></p> <p class="commenter-url"><a href="<?php the_author_meta('user_url',$user_id); ?>" target="_blank"><?php the_author_meta('user_url',$user_id); ?></a></p> </div><!-- .comment-metadata --> <?php if ( '0' == $comment->comment_approved ) : ?> <p class="comment-awaiting-moderation"><?php _e( 'Your comment is awaiting moderation.' ); ?></p> <?php endif; ?> </footer><!-- .comment-meta --> <div class="comment-content"> <?php comment_text(); ?> </div><!-- .comment-content --> <?php comment_reply_link( array_merge( $args, array( 'add_below' => 'div-comment', 'depth' => $depth, 'max_depth' => $args['max_depth'], 'before' => '<div class="reply">', 'after' => '</div>' ) ) ); ?> </article><!-- .comment-body --> <?php } } }

Come puoi notare confrontando il codice about con il contenuto dell'originale Walker_Comment, l'unica modifica necessaria era nel metodo html5_comment che fondamentalmente emette un commento in formato HTML5.

Dopodiché dobbiamo visualizzare l'elenco dei commenti utilizzando la funzione incorporata wp_list_comments con gli argomenti giusti per visualizzare l'oggetto HTML dell'albero dei commenti.

 wp_list_comments( array( 'page' => 143, 'walker' => new My_Comment_Walker ));

Abbiamo inserito il codice nella stessa riga di header.php che facevamo prima e utilizzato l'ID del post che contiene i commenti. Ovviamente, puoi semplicemente sostituire il codice relativo al commento del tuo modello e saltare l'opzione "pagina" in modo che si applichi a tutta la sezione dei commenti dei tuoi articoli.

Se aggiorni il front-end del tuo sito Web ora, noterai le voci di informazioni aggiuntive (biografia dell'autore e URL dell'autore) che abbiamo aggiunto nel codice personalizzato sopra.

Conclusione

Si spera che quanto sopra ti abbia dato un'idea dell'utilizzo della WordPress Walker Class. In tutti gli esempi abbiamo applicato le modifiche direttamente ai file del tema principale. Anche se va bene per scopi dimostrativi, ovviamente vorrai assicurarti di applicare le modifiche solo a un tema figlio in pratica per assicurarti che questi aggiornamenti non vengano sovrascritti quando WordPress o il tema utilizzato vengono aggiornati.