Familiarizarea cu clasa WordPress Walker

Publicat: 2020-11-27

Dacă 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ă.