WordPress oferuje kilka sposobów ingerencji w kod HTML menu, ale największy poziom kontroli można osiągnąć rozszerzając klasę Walker. Dzięki temu, zamiast tworzyć logikę niezbędną do poruszania się po „drzewku” elementów będziesz mógł skupić się na wynikowym kodzie HTML. Na szczęście nie jest to tak trudne, jak mogło by się wydawać.
Czym jest klasa Walker?
Klasa Walker pozwala na poruszanie się po danych o strukturze hierarchicznej. W WordPressie mamy do czynienia z tego typu danymi na przykład w przypadku kategorii, komentarzy czy stron. Walker jest klasą abstrakcyjną, co oznacza że nie korzysta się z niej bezpośrednio, ale należy ją odpowiednio rozszerzyć.
Rozszerzenia
WordPress posiada kilka wbudowanych rozszerzeń klasy Walker. Każda z nich tworzy kod HTML niezbędny do wyświetlenia odpowiednich elementów strony:
- Walker_Nav_Menu – menu,
- Walker_Page – lista stron,
- Walker_PageDropdown – rozwijana lista stron,
- Walker_Category – lista kategorii,
- Walker_CategoryDropdown – rozwijana lista kategorii,
- Walker_Comment – lista komentarzy.
Metody
Przyjrzyjmy się teraz bliżej metodom, jakie oferuje klasa Walker:
- walk:
jest to metoda która zwraca wygenerowany kod HTML. Funkcja „przechodzi” przez wszystkie elementy i wywołuje funkcjestart/end_lvl
orazstart/end_el
, które generują właściwe tagi HTML w zależności od umiejscowienia elementu w strukturze; - start_lvl:
generuje otwierający znacznik HTML elementu, który będzie zawierał elementy potomne
(tag<ul>
dla menu); - end_lvl:
generuje zamykający znacznik HTML elementu, który zawiera elementy potomne
(tag</ul>
dla menu); - start_el:
generuje otwierający znacznik HTML elementu
(tag<li>
oraz cały<a>
dla menu); - end_el:
generuje zamykający znacznik HTML elementu
(tag</li>
dla menu).
Tworząc własne rozszerzenie klasy Walker, nie musimy nadpisywać wszystkich wymienionych powyżej metod, a jedynie te, które generują interesujące nas elementy.
Tyle w kwestii wstępu, teraz czas na praktykę.
Tworzenie menu z opisami
W tym przykładzie stworzymy własne rozszerzenie klasy Walker_Nav_Menu
, dzięki któremu dla elementów menu najwyższego poziomu, obok tytułu wyświetlimy również opis.
Krok 1: Przygotowania
Zanim przejdziemy do pisania kodu, musimy zarejestrować nowy obszar menu a następnie stworzyć odpowiednie menu w panelu administratora.
Aby zarejestrować nowe menu, musimy wstawić następujący fragment kodu do pliku functions.php
:
register_nav_menus( array(
'primary-menu' => __('Menu główne'),
) );
Teraz możemy przejść do zakładki „Wygląd / Menu” w panelu administracyjnym. Klikając „Opcje ekranu” w górnym prawym rogu strony możemy zaznaczyć, aby przy każdym elemencie były wyświetlane dodatkowe pola. W naszym przykładzie potrzebujemy wypełnić również pole „Opis”, które domyślnie jest ukryte:
Po zapisaniu menu musimy pamiętać o przypisaniu go do właściwego obszaru w szablonie.
Krok 2: Rozszerzanie klasy Walker
Spójrzmy na docelową strukturę kodu HTML:
<ul>
<li><a href=”#”>Strona główna<em>...zacznij tutaj!</em></a></li>
<li><a href=”#”>Oferta<em>...co możemy dla Ciebie zrobić?</em></a></li>
<li><a href=”#”>Portfolio<em>...nasze realizacje!</em></a></li>
<li><a href=”#”>Kontakt<em>...napisz do nas!</em></a></li>
</ul>
Opis elementu menu powinien pojawić się w środku elementu <a>
, tuż po nazwie.
Wcześniej wspominałam, że rozszerzając klasę Walker nie ma potrzeby nadpisywania wszystkich dostępnych metod, możemy ograniczyć się do jednej wybranej metody. W tym przypadku potrzebujemy zmodyfikować tylko metodę start_el
, która odpowiada ze wyświetlenie otwierającego tagu <li>
oraz linka elementu menu.
Poniższy kod powinien się naleźć w pliku functions.php
:
class Description_Walker extends Walker_Nav_Menu{
...
}
Ciało klasy Description_Walker będzie bazować na klasie Walker_Nav_Menu
, znajdującej się w pliku nav-menu-template.php
. Aby ułatwić sobie zadanie i zapewnić poprawność kodu, skopiowałam całą funkcję start_el
z powyższego pliku (samego pliku nie należy zmieniać, gdyż należy on do core WordPressa), a następnie dokonałam w jej kodzie odpowiednich modyfikacji:
class Description_Walker extends Walker_Nav_Menu{
function start_el(&$output, $item, $depth, $args) {
global $wp_query;
$indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
$class_names = $value = '';
$classes = empty( $item->classes ) ? array() : (array) $item->classes;
$class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) );
$class_names = ' class="'. esc_attr( $class_names ) . '"';
$output .= $indent . '<li id="menu-item-'. $item->ID . '"' . $value . $class_names .'>';
$attributes = ! empty( $item->attr_title ) ? ' title="' . esc_attr( $item->attr_title ) .'"' : '';
$attributes .= ! empty( $item->target ) ? ' target="' . esc_attr( $item->target ) .'"' : '';
$attributes .= ! empty( $item->xfn ) ? ' rel="' . esc_attr( $item->xfn ) .'"' : '';
$attributes .= ! empty( $item->url ) ? ' href="' . esc_attr( $item->url ) .'"' : '';
if ($depth == 0) {
$description = ! empty( $item->description ) ? '<em>' . esc_attr( $item->description ).'</em>' : '';
} else {
$description = "";
}
$item_output = $args->before;
$item_output .= '<a'. $attributes .'>';
$item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID );
$item_output .= $description.$args->link_after;
$item_output .= '</a>';
$item_output .= $args->after;
$output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
}
}
W linijce 16 za pomocą zmiennej $depth
, sprawdzamy czy jesteśmy na najwyższym poziomie menu (wartość zmiennej $depth
wynosi zero) i w zależności od wyniku ustawiamy wartość zmiennej $description
. Następnie w linijce 25 dołączamy opis do wynikowego kodu HTML.
Krok 3: Wyświetlanie menu
Po wykonaniu tego kroku możemy już wyświetlić nasze menu wywołując funkcję wp_nav_menu
w odpowiednim miejscu w szablonie, na przykład w pliku header.php
, za pomocą następującego fragmentu kodu:
<?php wp_nav_menu( array('theme_location'=>'primary-menu','walker' => new Description_Walker())); ?>
Walker jest jednym z parametrów funkcji wp_nav_menu. Jako jego wartość podajemy nazwę jaką nadaliśmy naszemu rozszerzeniu klasy Walker. Należy również pamiętać, aby w parametrze ‘theme_location’ podać prawidłową nazwę menu, które zdefiniowaliśmy w pierwszym kroku za pomocą funkcji register_nav_menus
.
Podsumowanie
Mam nadzieję, że ten artykuł przybliżył Wam klasę Walker i wytłumaczył sposób jej działania. Menu jest tylko jednym z przykładów zastosowania tego rozwiązania. Warto pamiętać o tym również wtedy, gdy będziemy mieli do czynienia z kategoriami czy komentarzami.
Jeśli mimo wszystko nie czujesz się na siłach, aby napisać własne rozszerzenie klasy Walker, to w sieci możesz znaleźć gotowe rozwiązania np. na menu obrazkowe lub menu z nieklikalnym rodzicem.
Komentarze
[…] budowy menu w oparciu o listę nieuporządkowaną <ul>.W kolejnym artykule przedstawię Wam klasę Walker oraz pokażę jej zastosowanie w praktyce. Podobał się artykuł? Dodaj kanał RSS / Atom do swojego czytnika lub zapisz się na bezpłatny […]
odpowiedz[…] Wam, w jaki sposób wygenerować menu z własną strukturą kodu HTML, bez konieczności pisania rozszerzenia klasy Walker. Podobał się artykuł? Dodaj kanał RSS / Atom do swojego czytnika lub zapisz się na bezpłatny […]
odpowiedzDziękuję bardzo za ten tutorial… czegoś takiego właśnie szukałam od pewnego czasu :)
odpowiedzDzięki wielki – za ten artykuł. Dopiero zaczynam przygodę z WP, ale planuję duży serwis a tego typu rozwiązania na pewno się przydadzą.
P.S. Może tak artykuł o różnych klasach dla poszczególnych kategorii – tak aby na stronie głównej elementy przy danym artykule miały inne kolory – np dla kategorii A – elementy są niebieskie – dla kategorii B elementy są zielone :)
odpowiedz@Kamil, w tym akurat wielkiej filozofii nie ma.
odpowiedzhttps://codex.wordpress.org/Function_Reference/body_class i formatujesz elementy w odniesieniu do body.
Fajny tutorial, trochę wyjaśnił walkera.
odpowiedzKod walkera nie działa (wordpress zwraca błędy), ale sam artykuł spoko :-)
odpowiedzEee… po prostu mam nowszą wersję wp niż we wpisie… Sorry za lamerski komentarz.
odpowiedzDodaj własny komentarz
Odnośniki z innych stron
Lista innych stron, które w jakiś sposób odnoszą się do opublikowanej tutaj treści:
[…] budowy menu w oparciu o listę nieuporządkowaną <ul>.W kolejnym artykule przedstawię Wam klasę Walker oraz pokażę jej zastosowanie w praktyce. Podobał się artykuł? Dodaj kanał RSS / Atom do swojego czytnika lub zapisz się na bezpłatny […]
[…] Wam, w jaki sposób wygenerować menu z własną strukturą kodu HTML, bez konieczności pisania rozszerzenia klasy Walker. Podobał się artykuł? Dodaj kanał RSS / Atom do swojego czytnika lub zapisz się na bezpłatny […]