Do każdego elementu menu (li) WordPress automatycznie dodaje identyfikator (id) oraz kilka klas (class). Zdarzają się jednak sytuacje, w których chcielibyśmy je usunąć i zwiększyć czytelność kodu lub odpowiednio zmodyfikować zostawiając tylko te, których naprawdę potrzebujemy. Wtedy powinniśmy sięgnąć po odpowiednie filtry.
Usuwanie identyfikatorów i klas
Przyjrzyjmy się domyślnemu kodowi menu generowanemu przez funkcję wp_nav_menu
:
<ul>
<li id="menu-item-74" class="current-menu-item menu-item menu-item-type-custom menu-item-object-custom menu-item-74"><a href="http://mojastrona.pl/">Strona główna</a></li>
<li id="menu-item-71" class="menu-item menu-item-type-custom menu-item-object-page menu-item-71"><a href="http://mojastrona.pl/oferta/">Oferta</a></li>
<li id="menu-item-72" class="menu-item menu-item-type-custom menu-item-object-page menu-item-72"><a href="http://mojastrona.pl/portfolio/">Portfolio</a></li>
<li id="menu-item-73" class="menu-item menu-item-type-custom menu-item-object-page menu-item-73"><a href="http://mojastrona.pl/kontakt/">Kontakt</a></li>
</ul>
Jak widać dla każdego elementu <li>
mamy do dyspozycji kilka domyślnych klas. Warto zwrócić uwagę na to, że każda z nich ma swoje znaczenie. Możemy je zmodyfikować za pomocą następujących filtrów:
nav_menu_item_id
– identyfikator (wp_nav_menu
),nav_menu_css_class
– klasy (wp_nav_menu
),page_css_class
– klasy (wp_list_pages
).
Ostatni filtr dotyczy menu opartego o strony, wygenerowanego za pomocą funkcji wp_list_pages
, które często używane jest jako metoda zastępcza dla głównej nawigacji, na wypadek gdy użytkownik nie stworzy własnego menu w panelu administracyjnym.
W naszym przykładzie wykorzystamy je w następujący sposób:
add_filter('nav_menu_css_class', 'nav_css_filter', 10, 1);
add_filter('nav_menu_item_id', 'nav_css_filter', 10, 1);
add_filter('page_css_class', 'nav_css_filter', 10, 1);
function nav_css_filter($classes) {
$current = array('current-menu-item', 'current-menu-parent', 'current-menu-ancestor', 'current-page-ancestor');
if (is_array($classes)) {
$classes = array_intersect($classes, $current);
} else {
$classes = '';
}
return $classes;
}
W podanym przykładzie, usuwany jest identyfikator oraz wszystkie klasy, poza tymi podanymi w zmiennej $current
. W zmiennej tej umieściłam klasy, które są przypisywane aktywnemu elementowi menu oraz jego elementom nadrzędnym, co jest często wykorzystywane do poprawnego ich oznaczenia w nawigacji.
Po jego zastosowaniu kod HTML menu wygląda następująco:
<ul>
<li class="current-menu-item"><a href="http://mojastrona.pl/">Strona główna</a></li>
<li><a href="http://mojastrona.pl/oferta/">Oferta</a></li>
<li><a href="http://mojastrona.pl/portfolio/">Portfolio</a></li>
<li><a href="http://mojastrona.pl/kontakt/">Kontakt</a>
</ul>
Dodawanie własnych klas
Podany przykład to zaledwie jeden z pomysłów na wykorzystanie zaprezentowanych filtrów. Innym częstym zastosowaniem, jest dodawanie własnych klas, pod specyficznymi warunkami, na przykład dodanie klasy elementowi o określonej nazwie.
add_filter('nav_menu_css_class' , 'my_nav_class' , 10 , 2);
function my_nav_class($classes, $item){
if( $item->title == 'Kontakt'){
$classes[] = 'kontakt';
}
return $classes;
}
W powyższym przykładzie elementowi <li>
, zawierającemu pozycję menu o nazwie „Kontakt”, zostanie przypisana dodatkowa klasa „kontakt”.
Chciałam jeszcze zwrócić uwagę na obiekt $item
, ponieważ jest on kluczem do filtrowania pozycji menu. W kodzie powyżej, w linijce 3 skorzystałam z właściwości title obiektu $item
, a konkretnie sprawdziłam, czy ma ona wartość „Kontakt”. Obiekt $item
ma jednak znacznie więcej właściwości, na podstawie których możesz tworzyć własne warunki. Aby wyświetlić ich pełną listę, możesz skorzystać z funkcji var_dump
wywołując ją w środku funkcji my_nav_class
:
var_dump($item);
Oczywiście musisz pamiętać, aby później ją usunąć.
Na koniec mam dla was jeszcze jeszcze fragment kodu, który jest uogólnieniem przykładu powyżej. Tutaj każdemu elementowi menu dodajemy klasę odpowiadającą jego nazwie, a polskie znaki diakrytyczne są zastępowane literami z podstawowego alfabetu łacińskiego:
add_filter('nav_menu_css_class' , 'my_nav_class' , 10 , 2);
function my_nav_class($classes, $item){
$classes[] = sanitize_title_with_dashes(remove_accents($item->title));
return $classes;
}
Po jego zastosowaniu kod HTML menu wygląda następująco:
<ul>
<li class="current-menu-item strona-glowna"><a href="http://mojastrona.pl/">Strona główna</a></li>
<li class="oferta"><a href="http://mojastrona.pl/oferta/">Oferta</a></li>
<li class="portfolio"><a href="http://mojastrona.pl/portfolio/">Portfolio</a></li>
<li class="kontakt"><a href="http://mojastrona.pl/kontakt/">Kontakt</a>
</ul>
Podsumowanie
Możliwość kontrolowania klas przypisywanych elementom menu daje w praktyce ogromne możliwości dostosowania menu do własnych potrzeb a przy tym nie wymaga zaawansowanych umiejętności programistycznych.
W kolejnym artykule pokażę Wam, w jaki sposób wygenerować menu z własną strukturą kodu HTML, bez konieczności pisania rozszerzenia klasy Walker.
Komentarze
Bardzo przydatny post :) Dzięki
odpowiedzNa pewno się przyda:D
odpowiedzwydaje mi sie, ze efekt funkcji cleanname() mozna osiagnac robiac sanitize_title_with_dashes(remove_accents($str)) :)
odpowiedzHa! Racja, dzięki serdeczne. :-)
odpowiedzDzięki wielkie za post. Jestem początkujące jeśli chodzi o WP.
odpowiedzDodałem twój blog do ulubionych
fajny post.
a jak zrobic by aktywnie wybrana kategoria menu byla podswietlana lub po wybraniu danego posta powodowało podświetlenie odpowiadającej mu pozycji menu. w skrócie mówiać aktywn menu.
pozdrawiam
odpowiedzJeśli kategoria do której należy post znajduje się w menu, to podczas wyświetlania posta zostanie do niej dodana klasa current-post-parent
odpowiedza czy mam to wywolac w pliku functions.php? mozna jakis przyklad.
odpowiedzpozdrawiam
Niczego nie trzeba wywoływać, WordPress domyślnie nada taką klasę odpowiedniemu elementowi w menu. Wystarczy dodać odpowiednie style w pliku style.css, np.
odpowiedzdzieki bardzo. a jesli usune wszystkie id itp jak podałaś wyżej czy nadal bedzie to funkcjonowac? potestuje:)
pozdrawiam
odpowiedzto działa tylko jak wybieram z menu głównego. jak klikam na jakis TAG z chmury to przenosi mnie do artykułu ale juz w menu nie ma class-y current-post-parrent.
czyli jak to obejsc znam php, ale szukam latwej opcji bez kombinacji i ingernecji w baze itp.
pozdrawiam i dzieki z góry za odpowiedz.
odpowiedzTo rozwiązanie działa dla kategorii, nie dla tagów. Tak na prawdę jest kilka klas które są przypisywane do elementów menu, w zależności od tego co ono reprezentuje (stronę, kategorię itd.) i w jakiej jest relacji do wyświetlanej aktualnie strony. Temat jest dość rozległy i opisywanie go tutaj nie ma sensu. Chyba powstanie na ten temat osobny artykuł :)
Ale w dużym skrócie – po pierwsze nie usuwaj domyślnych klas (przykład z artykułu) i dodaj style dla klas:
To powinno pomóc. Przyjrzyj się też dokładnie jak wygląda kod menu (jakie klasy dodawane są do li) na różnych podstronach serwisu.
odpowiedzA w jaki sposób do linków w menu dodać atrybut title ?
odpowiedzWystarczy że tworząc menu w panelu administracyjnym, dla każdej pozycji wypełnisz pole 'Atrybut „Tytuł”’.
odpowiedzA ja nie mogę sobie poradzić aby dodać atrybut class – jak to zrobić?
odpowiedzjeszcze dodam dla tych którzy będą szukali, że zmian dokonujemy w pliku wp-includes/nav-menu-template.php :)
odpowiedzWprost przeciwnie – nie wprowadzamy zmian w plikach WordPressa a jedynie modyfikujemy funkcje za pomocą odpowiednich filtrów (te z kolei możemy zamieścić w pliku functions.php, który znajduje się w katalogu aktualnie używanego motywu graficznego).
odpowiedzWielkie dzięki. Dzięki temu wpisowi oszczędziłem masę czasu! :)
odpowiedzdzisiaj poprawiałem kolejny motyw według instrukcji, wszystko działa, dzięki wielkie!
odpowiedzCiekawe. Rozumiem, że klasy i kontrolujące je filtry są miejscem przewidzianym przez autorów WP właśnie do zaszycia takich dodatkowych reguł. Czy jest gdzieś taki spis sztuczek – jak chcesz dostosować zachowanie X to zrób Y?
odpowiedzJeżeli chodzi o akcje i filtry, to:
odpowiedzhttps://codex.wordpress.org/Plugin_API/Action_Reference
https://codex.wordpress.org/Plugin_API/Filter_Reference
http://adambrown.info/p/wp_hooks/
…
generalnie https://codex.wordpress.org/
-reszta, to inne materiały zgromadzone w sieci (w tym na pozostałych stronach wordpressa) ….a także po prostu samodzielna analiza kodu plików wp.
Dodaj własny komentarz