Familiarizarea cu clasa WordPress Walker
Publicat: 2020-11-27Dacă nu sunteți familiarizat cu clasa Walker, pregătește-te să fii uimit de cât de utilă poate fi pentru munca ta. Clasa WordPress Walker a fost implementată în WordPress 2.1 pentru a oferi dezvoltatorilor un mijloc de a traversa structuri de date asemănătoare arborelui în scopul redării HTML. În acest articol vom studia cum funcționează parametrul walker și cum să personalizăm ieșirile în meniuri, categorii și comentarii.
Haide să mergem!
Prezentare generală a clasei Walker
În WordPress, vedem frecvent obiecte care au o structură ierarhică, cum ar fi meniuri de navigare, liste de categorii sau liste de comentarii
După cum probabil știți deja, în cazul unei structuri de date arbore, unele elemente sunt părinți, iar altele sunt copiii lor. „Postează Subcategoria 1” este un copil pentru „Postează Categoria 1”, un răspuns la un comentariu este un comentariu secundar la comentariul în sine, iar „Serviciul 1” este un element de meniu copil pentru elementul „Servicii”.
Walker-ul este numit astfel, deoarece pur și simplu „plimbă” prin fiecare obiect sau matrice asociativă și execută o funcție la fiecare nod. Ceea ce ne-am dori să obținem prin aceasta este capacitatea de a enumera link-urile de „nivel superior”, cu articolele lor „copil” în moduri diferite, în funcție de cerințele noastre specifice.
Cu alte cuvinte, WordPress vă oferă o structură standard <ul> <li> și îi puteți personaliza argumentele, dar, extinzând Walker-ul, puteți personaliza structura în sine modificându-i conținutul HTML.
Fișierul de bază legat de clasa Walker este wp-includes/class-wp-walker.php
și guvernează toate tipurile de date tip arbore pe care le-am enumerat anterior.
Deoarece este o clasă PHP abstractă, pentru a genera orice HTML, aceasta trebuie extinsă de către dezvoltator care va defini o versiune personalizată a proprietăților și metodelor sale. Deci, să studiem clasele copil din fișierul class-wp-walker.php
unul câte unul.
Clasele pentru copii
$tree_type
este o variabilă opțională care vine într-un tip sau o matrice de tipuri și definește ce se ocupă de clasă.
public $tree_type = array( 'post_type', 'taxonomy', 'custom' );
$db_fields
este o variabilă obligatorie și definește ce câmpuri de bază de date să folosească. Această proprietate este o matrice cu două chei: „parent” și „id” ale căror valori sunt numele proprietăților obiectului care dețin id-ul părinte și, respectiv, id-ul articolului.
public $db_fields = array( 'parent' => 'menu_item_parent', 'id' => 'db_id', );
Proprietatea $max_pages
este de asemenea opțională și rolul ei este de a specifica numărul maxim de pagini parcurse de mersătorul paginat.
public $max_pages = 1;
$has_children
se explică de la sine și are o valoare adevărată sau falsă, în funcție de faptul dacă elementul curent are copii.
public $has_children;
Metoda start_lvl
este executată pe rădăcina unui nou obiect asemănător arborelui și preia argumentele $output, $depth și $args.
public function start_lvl( &$output, $depth = 0, $args = array() ) {}
Argumentul $output
adaugă conținut suplimentar, $depth
specifică adâncimea articolului și $args
este o serie de argumente suplimentare.
Metoda end_lvl
închide orice etichetă a fost deschisă anterior prin metoda start_lvl.
public function end_lvl( &$output, $depth = 0, $args = array() ) {}
Metoda start_el
(Start Element) este utilizată pentru a afișa eticheta HTML de deschidere pentru elementul curent. În cazul unui meniu, de exemplu, este de obicei o etichetă <li>.
public function start_el( &$output, $object, $depth = 0, $args = array(), $current_object_id = 0 ) {}
Funcția end_el
este apelată după ce Walker trece un element cu toți copiii lui și returnează o etichetă de închidere.
public function end_el( &$output, $object, $depth = 0, $args = array() ) {}
display_element
afișează de fapt elementele obiectului arbore. Apelează funcțiile start_el
, start_lvl
, display_element
, end_lvl
, end_el
în această ordine. Acum să aruncăm o privire la argumentele sale.
- $element : elementul curent
- $children_elements : toate elementele copil ale obiectului arbore
- $max_depth : limita maximă de adâncime pe care o putem explora
- $depth : nivelul la care ne aflăm în prezent
- $args : argumente opționale suplimentare
- $output : ieșirea HTML curentă.
Vom demonstra acum câte un exemplu pentru fiecare tip de date utilizând o instalare WordPress cu tema Twenty Twenty activată.
Personalizarea unei structuri de meniu
Funcția wp_nav_menu() pe care WordPress o folosește pentru afișarea meniurilor este inclusă în fișierul wp-includes/nav-menu-template.php
. În acest fișier, WordPress solicită și clasa Walker_Nav_Menu în jurul liniei 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 ); }
Clasa Walker_Nav_Menu
este definită în fișierul wp-includes/class-walker-nav-menu.php
și practic este tot conținutul fișierului.
Pentru a afișa rezultatul meniului, codul WordPress folosește proprietățile și metodele clasei Walker_Nav_Menu descrise în acest fișier.
Să remediem, de exemplu, o problemă bine cunoscută cu care se confruntă mulți dezvoltatori, care este schimbarea elementului pentru elementele de meniu părinte cu un link personalizat gol („#”) pentru a preveni vizitatorii să facă clic pe ele.
Pentru a ne permite să comparăm rezultatele noastre, vom crea mai întâi o clonă a meniului primar adăugând codul de mai jos în header.php
imediat după începerea elementului <header>
.
<header class="header-footer-group" role="banner"> <?php wp_nav_menu( array( 'menu_class' => 'primary-menu reset-list-style' ) ); ?>
Ceea ce am făcut de fapt aici a fost să regenerăm meniul principal și să moștenim funcționalitatea sa drop-down și CSS prin adăugarea claselor sale primary-menu reset-list-style
la noul meniu, de asemenea.
Acum, în fișierul nostru functions.php
vom crea o clasă care extinde clasa Walker_Nav_Menu. Deoarece dorim să schimbăm tipul de element, vom înlocui metoda 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>'; } } } }
Așa că am împachetat fiecare element în mod normal cu o etichetă <li> și apoi, cu utilizarea instrucțiunii if, am adăugat un interval când un link este „#” și o etichetă <a> pentru restul.
Pentru a aplica acest lucru în meniul nostru, ne întoarcem la codul de meniu pe care l-am adăugat anterior și specificăm parametrul walker:
wp_nav_menu( array( 'walker' => new My_Custom_Nav_Walker, 'menu_class' => 'primary-menu reset-list-style' ) );
Acum rezultatul ar trebui să arate astfel:
Dacă treceți acum cursorul peste „Servicii” din elementul de meniu, nu va apărea niciun cursor manual și nici pe acest element de meniu nu se poate face clic. Totuși, submeniul drop-down va fi afișat corect.
Personalizarea categoriilor
Mai întâi intră în zona de administrare și creează câteva categorii de postări și subcategorii pentru a avea un arbore de categorii pentru demonstrație.
După aceea vom genera o listă de categorii adăugând acest cod undeva în header.php
. Puteți să-l puneți după începutul elementului antet ca anterior.
<header class="header-footer-group" role="banner"> <?php wp_list_categories( array('hide_empty' => FALSE) ); ?>
Funcția este o funcție WordPress încorporată care generează o ieșire HTML a unui arbore de categorii. În mod implicit, arată doar categoriile care conțin postări, motiv pentru care am folosit opțiunea hide_empty
pentru a afișa și categoriile goale și pentru a vedea întreaga ierarhie în sensul acestui exemplu.
Ca și anterior, putem crea o clasă personalizată în functions.php
pentru a extinde clasa implicită Walker_Category care este descrisă în fișierul wp-includes/class-walker-category.php
și să aplicăm modificările noastre. De exemplu, vom adăuga câteva pictograme înaintea numelor categoriilor adăugând acest cod:
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); } } }
Pentru ca acest lucru să funcționeze, desigur, ar trebui să pregătiți imagini adecvate și să le salvați în folderul definit. Aceste imagini ar trebui să urmeze un format de nume specific, care în acest exemplu ar fi „post-category-1”, „post-subcategory-1”, „post-category-3.jpg” etc.
Personalizarea comentariilor
Actualizarea meniului și a listei de categorii este de departe cel mai frecvent motiv pentru care ați putea personaliza o clasă Walker, dar uneori trebuie să implementați aceeași tehnică și pentru comentarii. Dacă, de exemplu, doriți să schimbați metainformațiile de lângă imaginea Gravatar din secțiunea de comentarii, putem face acest lucru cu ușurință extinzând clasa Walker_Comment găsită în fișierul wp-includes/class-walker-comment.php.
În fișierul functions.php adăugați acest cod
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 } } }
După cum puteți observa prin compararea codului despre cu conținutul originalului Walker_Comment, singura modificare necesară a fost metoda html5_comment
care, practic, scoate un comentariu în format HTML5.
După aceea, trebuie să afișam lista de comentarii utilizând funcția încorporată wp_list_comments cu argumentele potrivite pentru a afișa HTML obiectul arborelui de comentarii.
wp_list_comments( array( 'page' => 143, 'walker' => new My_Comment_Walker ));
Am inserat codul în aceeași linie de header.php pe care am făcut-o înainte și am folosit ID-ul postării care conține comentariile. Desigur, puteți pur și simplu să înlocuiți codul legat de comentarii al șablonului dvs. și să săriți peste opțiunea „pagină”, astfel încât să se aplice tuturor secțiunii de comentarii ale articolelor dvs.
Dacă vă reîmprospătați site-ul web acum, veți observa intrările de informații suplimentare (biografia autorului și adresa URL a autorului) pe care le-am adăugat în codul personalizat de mai sus.
Concluzie
Sperăm că cele de mai sus v-au oferit câteva informații despre utilizarea clasei WordPress Walker. În toate exemplele, am aplicat modificări direct fișierelor teme de bază. Deși este în regulă în scopuri demonstrative, veți dori, evident, să vă asigurați că aplicați editări doar unei teme secundare în practică, pentru a vă asigura că aceste actualizări nu sunt suprascrise atunci când fie WordPress, fie tema utilizată este actualizată.