Introduzione
Come sappiamo la funzione wp_nav_menu di WordPress ci consente di visualizzare uno specifico menu in una determinata posizione del template.
Pur essendo molto potente e facilmente configurabile, grazie agli innumerevoli parametri messi a disposizione, a volte si ha la necessità di correggere il suo funzionamento aggiungendo classi css in base all’elemento attualmente selezionato.
Supponiamo quindi di avere un menu di questo tipo, e di essere all’interno della pagina contatti; il risultato che vogliamo ottenere è pressapoco questo:
- Home Page
- – Chi siamo
- – Contatti
Vogliamo cioè che all’elemento “Contatti” venga applicata una classe “active” o “current”, per mostrarlo con una formattazione differente (nel caso in esempio con font-weight: bold;).
Andando ad analizzare il sorgente generato da WordPress ci accorgiamo che l’elemento è contenuto come link <a> all’interno di un tag <li>, ed analizzando <li> ci accorgiamo che vengono già aggiunte delle classi ben precise, ad esempio:
1 | <li id="menu-item-30" class="menu-item menu-item-type-post_type menu-item-object-page current-menu-item page_item page-item-28 current_page_item menu-item-30"><a href="https://miosito.it/contatti/">Contatti</a></li> |
Come possiamo vedere WordPress aggiunge la classe “current-menu-item” all’elemento che è correntemente selezionato.
A questo punto abbiamo due alternative:
- Creiamo una regola specifica nel nostro style.css utilizzando il nome della classe fornita automaticamente dal menu.
Esempio:CSS1.current-menu-item { font-weight: bold; } - Abbiamo già una nostra classe (ad esempio: “active”) e vogliamo semplicemente che WordPress la aggiunga all’elemento attivo, quindi la nostra più tutte le classi che inserisce già di suo.
In quest’ultimo caso dobbiamo per forza aggiungere del codice al file functions.php, in modo da dire a WordPress cosa fare e quale classe aggiungere.
Ecco il codice da inserire nel functions.php:
1 2 3 4 5 6 7 8 | //aggiunge la classe active ai menu add_filter('nav_menu_css_class', 'special_nav_class',10,2); function special_nav_class($classes, $item){ if( in_array('current-menu-item', $classes) ){ $classes[] = 'active'; } return $classes; } |
Ecco il codice spiegato in breve:
Riga 2: aggiungo un filtro che esegua la funzione special_nav_class quando viene eseguita la funzione nav_menu_css_class (che è a sua volta richiamato da wp_nav_menu).
Riga 3: creo la funzione special_nav_class al quale passo i due argomenti $classes e $item restituiti dal filtro richiamato nella riga 2.
Riga 4: se trovo il valore “current-menu-item”, nell’array $classes (ossia tutte le classi che vengono applicate in origine da WordPress), allora significa che mi trovo nell’elemento del menu attualmente selezionato.
Riga 5: aggiungo alla fine dell’array, il nome della mia classe (nell’esempio “active”).
Riga 7: restituisco l’array aggiornato al filtro ‘nav_menu_css_class’.
Risultato finale (come vedete ora viene aggiunta la classe active alla fine di tutto):
1 | <li id="menu-item-30" class="menu-item menu-item-type-post_type menu-item-object-page current-menu-item page_item page-item-28 current_page_item menu-item-30 active"><a href="https://miosito.it/contatti/">Contatti</a></li> |
Potremmo aver finito qui, tuttavia esiste anche un’altro caso in cui ad esempio il menu originale era stato concepito per avere la classe “active” non dentro al tag <li> ma dentro al suo nodo interno, generalmente un link e quindi dentro ad un tag <a>
Esempio:
1 | <li class="tutte-le-classi"><a href="https://miosito.it/contatti/" class="active">Contatti</a></li> |
In questo caso abbiamo bisogno di intercettare l’elemento <li> che contiene la classe “active” ed inserirla anche dentro al suo elemento <a>.
Per farlo è necessario aver già eseguito la modifica nel file functions.php e modificare il metodo in cui visualizziamo il menu nel template.
Se prima ad esempio utilizzavate il classico:
1 | wp_nav_menu(array ('theme_location'=> 'main-menu', + eventuali altri parametri originali); |
Ora dovete fare in modo che tutto il codice del menu venga inserito in una variabile, in modo da poterlo modificare.
1 2 | $menu = wp_nav_menu(array ('theme_location'=> 'main-menu', + eventuali altri parametri originali, 'echo'=> false)); echo str_replace('active"><a href','active"><a class="active" href', $menu); |
Il codice permette di rilevare il punto in cui WordPress aggiunge la classe all’elemento attivo, e la aggiunge anche all’elemento <a> al suo interno.
Il codice è testato fino alla versione 4.9.2 di WP, dovrebbe rimanere funzionante per molto tempo, a meno che WordPress non decida di modificare drasticamente la struttura della funzione wp_nav_menu in una delle sue prossime versioni; ipotesi che ritengo abbastanza improbabile.