Zapoznanie się z klasą WordPress Walker

Opublikowany: 2020-11-27

Jeśli nie znasz klasy Walker, przygotuj się na zaskoczenie, jak pomocne może być w Twojej pracy. Klasa WordPress Walker została zaimplementowana w WordPress 2.1, aby zapewnić programistom możliwość przechodzenia przez struktury danych przypominające drzewa w celu renderowania HTML. W tym artykule zbadamy, jak działa parametr chodzika i jak dostosować wyjścia w menu, kategoriach i komentarzach.

Kontynuujmy!

Przegląd klas Walkera

W WordPressie często widzimy obiekty o strukturze hierarchicznej, takie jak menu nawigacyjne, listy kategorii lub listy komentarzy

Jak być może już wiesz, w przypadku struktury danych w postaci drzewa, niektóre elementy są rodzicami, a inne są ich dziećmi. „Podkategoria postu 1” jest elementem podrzędnym „Kategorii postu 1”, odpowiedź na komentarz jest komentarzem podrzędnym do samego komentarza, a „Usługa 1” jest elementem menu podrzędnego elementu „Usługi”.

Walker jest tak nazwany, ponieważ po prostu „przechodzi” przez każdy obiekt lub tablicę asocjacyjną i wykonuje funkcję w każdym węźle. To, co chcielibyśmy dzięki temu osiągnąć, to możliwość wyświetlania linków „najwyższego poziomu” wraz z ich „podrzędnymi” elementami na różne sposoby, zgodnie z naszymi konkretnymi wymaganiami.

Innymi słowy, WordPress oferuje standardową strukturę <ul> <li> i możesz dostosować jej argumenty, ale poprzez rozszerzenie Walkera możesz dostosować samą strukturę, modyfikując jej zawartość HTML.

Podstawowym plikiem powiązanym z klasą Walker jest wp-includes/class-wp-walker.php i zarządza wszystkimi typami danych podobnych do drzewa, które wymieniliśmy wcześniej.

Ponieważ jest to abstrakcyjna klasa PHP, aby wygenerować dowolny kod HTML, musi zostać rozszerzony przez programistę, który zdefiniuje dostosowaną wersję jej właściwości i metod. Przeanalizujmy więc kolejno klasy potomne w pliku class-wp-walker.php .

Zajęcia dla dzieci

$tree_type jest opcjonalną zmienną, która znajduje się w typie lub tablicy typów i definiuje, co obsługuje klasa.

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

$db_fields jest zmienną wymaganą i określa, których pól bazy danych użyć. Ta właściwość jest tablicą z dwoma kluczami: 'parent' i 'id', których wartości są nazwami właściwości obiektów, które przechowują odpowiednio id rodzica i id elementu.

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

Właściwość $max_pages jest również opcjonalna, a jej rolą jest określenie maksymalnej liczby stron przechodzonych przez stronicowany walker.

 public $max_pages = 1;

$has_children jest właściwie oczywista i ma wartość true lub false w zależności od tego, czy bieżący element ma dzieci.

 public $has_children;

Metoda start_lvl jest wykonywana na korzeniu nowego obiektu podobnego do drzewa i przyjmuje argumenty $output, $depth i $args.

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

Argument $output dołącza dodatkową zawartość, $depth określa głębokość elementu, a $args to tablica dodatkowych argumentów.

Metoda end_lvl zamyka każdy tag, który został wcześniej otwarty przez metodę start_lvl.

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

Metoda start_el (element startowy) służy do wyświetlania otwierającego znacznika HTML dla bieżącego elementu. Na przykład w przypadku menu jest to zwykle znacznik <li>.

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

Funkcja end_el jest wywoływana po tym, jak Walker przekaże element ze wszystkimi jego dziećmi i zwróci tag zamykający.

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

display_element faktycznie wyświetla elementy obiektu drzewa. Wywołuje start_el , start_lvl , display_element , end_lvl , end_el w tej kolejności. Przyjrzyjmy się teraz jego argumentom.

  • $element : bieżący element
  • $children_elements : wszystkie elementy potomne obiektu drzewa
  • $max_depth : maksymalny limit głębokości, który możemy zbadać
  • $głębokość : Poziom, na którym obecnie się znajdujemy
  • $args : dodatkowe argumenty opcjonalne
  • $output : Bieżące wyjście HTML.

Zademonstrujemy teraz jeden przykład dla każdego typu danych, używając instalacji WordPress z aktywowanym motywem Twenty Twenty.

Dostosowywanie struktury menu

Funkcja wp_nav_menu(), której WordPress używa do wyświetlania menu, jest zawarta w pliku wp-includes/nav-menu-template.php . W tym pliku WordPress wywołuje również klasę Walker_Nav_Menu wokół linii 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 ); }

Klasa Walker_Nav_Menu jest zdefiniowana w pliku wp-includes/class-walker-nav-menu.php i zasadniczo jest to cała zawartość pliku.

Aby wyświetlić dane wyjściowe menu, kod WordPressa wykorzystuje właściwości i metody klasy Walker_Nav_Menu opisane w tym pliku.

Rozwiążmy na przykład dobrze znany problem, z którym boryka się wielu programistów, który polega na zmianie elementu dla pozycji menu nadrzędnego za pomocą pustego niestandardowego linku ('#'), aby uniemożliwić odwiedzającym ich kliknięcie.

Aby umożliwić nam porównanie naszych wyników, najpierw utworzymy klon głównego menu, dodając poniższy kod w pliku header.php zaraz po rozpoczęciu elementu <header> .

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

W rzeczywistości zrobiliśmy tutaj regenerację menu głównego i odziedziczyliśmy jego rozwijaną funkcjonalność i CSS, dodając również jego klasy do nowego menu w primary-menu reset-list-style .

Teraz w naszym pliku functions.php utworzymy klasę, która rozszerza klasę Walker_Nav_Menu. Ponieważ chcemy zmienić typ elementu, nadpiszemy metodę 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>'; } } } }

Tak więc owinęliśmy każdy element normalnie tagiem <li>, a następnie za pomocą instrukcji if dodaliśmy span, gdy link to „#” i tag <a> dla reszty.

Aby zastosować to do naszego menu, wracamy do kodu menu, który dodaliśmy wcześniej i określamy parametr walkera:

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

Teraz wynik powinien wyglądać tak:

Jeśli teraz najedziesz kursorem na „Usługi” w elemencie menu, nie pojawi się kursor w kształcie dłoni, ani nie będzie można kliknąć tej pozycji menu. Rozwijane podmenu będzie jednak nadal wyświetlane poprawnie.

Dostosowywanie kategorii

Najpierw przejdź do obszaru administracyjnego i utwórz kilka kategorii postów i podkategorii, aby mieć drzewo kategorii do demonstracji.

Następnie wygenerujemy listę kategorii, dodając ten kod gdzieś w header.php . Możesz umieścić go po rozpoczęciu elementu nagłówka, jak poprzednio.

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

Funkcja jest wbudowaną funkcją WordPress, która generuje wynik HTML drzewa kategorii. Domyślnie pokazuje tylko kategorie zawierające posty, dlatego użyliśmy opcji hide_empty , aby wyświetlić również puste kategorie i zobaczyć całą hierarchię na potrzeby tego przykładu.

Jak poprzednio, możemy stworzyć niestandardową klasę w functions.php aby rozszerzyć domyślną klasę Walker_Category opisaną w pliku wp-includes/class-walker-category.php i zastosować nasze zmiany. Na przykład dodamy kilka ikon przed nazwami kategorii, dodając ten kod:

 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); } } }

Aby to zadziałało należałoby oczywiście przygotować odpowiednie obrazy i zapisać je w zdefiniowanym folderze. Te obrazy musiałyby mieć określony format nazwy, który w tym przykładzie byłby „post-category-1”, „post-subcategory-1”, „post-category-3.jpg” itp.

Dostosowywanie komentarzy

Aktualizacja menu i listy kategorii jest zdecydowanie najczęstszym powodem, dla którego możesz dostosować klasę Walkera, ale czasami musisz zaimplementować tę samą technikę również w przypadku komentarzy. Jeśli na przykład chcesz zmienić meta informacje obok obrazu Gravatara w sekcji komentarzy, możemy to łatwo zrobić, rozszerzając klasę Walker_Comment znalezioną w pliku wp-includes/class-walker-comment.php.

W pliku functions.php dodaj ten kod

 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 } } }

Jak można zauważyć porównując kod about z zawartością oryginalnego Walker_Comment, jedyną niezbędną zmianą była metoda html5_comment , która zasadniczo wyświetla komentarz w formacie HTML5.

Następnie musimy wyświetlić listę komentarzy za pomocą wbudowanej funkcji wp_list_comments z odpowiednimi argumentami, aby wyświetlić obiekt HTML podobny do drzewa komentarzy.

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

Wstawiliśmy kod w tym samym wierszu pliku header.php, co wcześniej i użyliśmy identyfikatora posta zawierającego komentarze. Oczywiście możesz po prostu zastąpić kod związany z komentarzami swojego szablonu i pominąć opcję „strona”, aby miała zastosowanie do wszystkich sekcji komentarzy do twoich artykułów.

Jeśli odświeżysz teraz interfejs swojej witryny, zauważysz dodatkowe wpisy informacyjne (bio autora i adres URL autora), które dodaliśmy w powyższym niestandardowym kodzie.

Wniosek

Mamy nadzieję, że powyższe informacje dały ci pewien wgląd w korzystanie z klasy WordPress Walker. We wszystkich przykładach zastosowaliśmy zmiany bezpośrednio do podstawowych plików motywów. Chociaż jest to w porządku do celów demonstracyjnych, oczywiście musisz upewnić się, że w praktyce stosujesz tylko zmiany do motywu podrzędnego, aby mieć pewność, że te aktualizacje nie zostaną nadpisane po zaktualizowaniu WordPressa lub używanego motywu.