publikacja: 2 lipca 2012, autor: , komentarzy 21 https://wpninja.pl/artykuly/menu-wordpress-zarzadzanie-identyfikatorami-i-klasami/

Menu WordPress – zarządzanie identyfikatorami i klasami

Menu WordPress – zarządzanie identyfikatorami i klasami

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:

 
   "menu-item-74""current-menu-item menu-item menu-item-type-custom menu-item-object-custom menu-item-74""http://mojastrona.pl/"Strona główna
   "menu-item-71""menu-item menu-item-type-custom menu-item-object-page menu-item-71""http://mojastrona.pl/oferta/"Oferta
   "menu-item-72""menu-item menu-item-type-custom menu-item-object-page menu-item-72""http://mojastrona.pl/portfolio/"Portfolio
   "menu-item-73""menu-item menu-item-type-custom menu-item-object-page menu-item-73""http://mojastrona.pl/kontakt/"Kontakt
 

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:

 
   "current-menu-item""http://mojastrona.pl/"Strona główna
   "http://mojastrona.pl/oferta/"Oferta
   "http://mojastrona.pl/portfolio/"Portfolio
   "http://mojastrona.pl/kontakt/"Kontakt
 

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:

 
   "current-menu-item strona-glowna""http://mojastrona.pl/"Strona główna
   "oferta""http://mojastrona.pl/oferta/"Oferta
   "portfolio""http://mojastrona.pl/portfolio/"Portfolio
   "kontakt""http://mojastrona.pl/kontakt/"Kontakt
 

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

  1. Reniferu 5 lat temu:

    Bardzo przydatny post :) Dzięki

    odpowiedz
  2. Levre 5 lat temu:

    Na pewno się przyda:D

    odpowiedz
  3. kminek 5 lat temu:

    wydaje mi sie, ze efekt funkcji cleanname() mozna osiagnac robiac sanitize_title_with_dashes(remove_accents($str)) :)

    odpowiedz
    1. Szymon Skulimowski 5 lat temu:

      Ha! Racja, dzięki serdeczne. :-)

      odpowiedz
  4. Tomek 5 lat temu:

    Dzięki wielkie za post. Jestem początkujące jeśli chodzi o WP.
    Dodałem twój blog do ulubionych

    odpowiedz
  5. bogdan 5 lat temu:

    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

    odpowiedz
    1. Ola 5 lat temu:

      Jeś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

      odpowiedz
    2. bogdan 5 lat temu:

      a czy mam to wywolac w pliku functions.php? mozna jakis przyklad.
      pozdrawiam

      odpowiedz
    3. Ola 5 lat temu:

      Niczego nie trzeba wywoływać, WordPress domyślnie nada taką klasę odpowiedniemu elementowi w menu. Wystarczy dodać odpowiednie style w pliku style.css, np.

      .current-post-parent {
      background: #f00;
      }
      odpowiedz
    4. bogdan 5 lat temu:

      dzieki bardzo. a jesli usune wszystkie id itp jak podałaś wyżej czy nadal bedzie to funkcjonowac? potestuje:)

      pozdrawiam

      odpowiedz
    5. bogdan 5 lat temu:

      to 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.

      odpowiedz
    6. Ola 5 lat temu:

      To 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:

      .current-menu-item,
      .current-page-ancestor,
      .current-post-ancestor

      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.

      odpowiedz
  6. Marcin 5 lat temu:

    A w jaki sposób do linków w menu dodać atrybut title ?

    odpowiedz
    1. Ola 5 lat temu:

      Wystarczy że tworząc menu w panelu administracyjnym, dla każdej pozycji wypełnisz pole ‚Atrybut „Tytuł”‚.

      odpowiedz
    2. Michał 2 lata temu:

      A ja nie mogę sobie poradzić aby dodać atrybut class – jak to zrobić?

      odpowiedz
  7. Marcin 5 lat temu:

    jeszcze dodam dla tych którzy będą szukali, że zmian dokonujemy w pliku wp-includes/nav-menu-template.php :)

    odpowiedz
    1. Szymon Skulimowski 3 lata temu:

      Wprost 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).

      odpowiedz
  8. Camel 4 lata temu:

    Wielkie dzięki. Dzięki temu wpisowi oszczędziłem masę czasu! :)

    odpowiedz
  9. geek 4 lata temu:

    dzisiaj poprawiałem kolejny motyw według instrukcji, wszystko działa, dzięki wielkie!

    odpowiedz
  10. Klasa 3 lata temu:

    Ciekawe. 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?

    odpowiedz
    1. Paweł Knapek 3 lata temu:

      Jeżeli chodzi o akcje i filtry, to:
      http://codex.wordpress.org/Plugin_API/Action_Reference
      http://codex.wordpress.org/Plugin_API/Filter_Reference
      http://adambrown.info/p/wp_hooks/

      generalnie http://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.

      odpowiedz

Dodaj własny komentarz