Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

WordPress, personalizzare i menu

Impariamo ad apportare modifiche complesse alla struttura predefinita dei menu di WordPress.
Impariamo ad apportare modifiche complesse alla struttura predefinita dei menu di WordPress.
Link copiato negli appunti

Da un punto di vista strutturale, per WordPress un menu di navigazione è una semplice lista non ordinata di collegamenti ipertestuali. Naturalmente, esigenze specifiche di sviluppo possono richiedere la creazione di menu complessi, per i quali la struttura predefinita non è sufficiente. A partire da WordPress 3 è, però, possibile personalizzare i menu predefiniti in modo avanzato e senza grandi difficoltà.

Il framework permette infatti di creare sistemi di navigazione alternativi, mega-menu, ed elenchi arricchiti da elementi grafici non gestibili con i soli fogli di stile.

Aggiungere un menu ad un tema di WordPress

Quando si sviluppa o si modifica un tema, per inserire un menu in una specifica area della pagina, bisogna eseguire due operazioni: per prima cosa il menu va registrato nel file functions.php, grazie alla funzione register_nav_menu:

function register_my_custom_menu() {
register_nav_menu( 'custom', __( 'Custom Menu' ) );
}
add_action( 'init', 'register_my_custom_menu' );

Una volta registrato, il menu appare nel pannello di amministrazione, nell'elenco delle posizioni del tema.

Figura 1. Le impostazioni del menu con un menu personalizzato
Le impostazioni del menu con un menu personalizzato

La seconda operazione consiste nella collocazione del menu nell'area della pagina stabilita. La funzione wp_nav_menu genera l'output HTML, composto da una semplice lista non ordinata. Per creare un menu di navigazione personalizzato, bisogna invocare wp_nav_menu all'interno del file header.php.

La funzione accetta come argomento un array di parametri, strutturato come segue:

$defaults = array(
'theme_location' => '',
'menu' => '',
'container' => 'div',
'container_class' => '',
'container_id' => '',
'menu_class' => 'menu',
'menu_id' => '',
'echo' => true,
'fallback_cb' => 'wp_page_menu',
'before' => '',
'after' => '',
'link_before' => '',
'link_after' => '',
'items_wrap' => '<ul id="%1$s" class="%2$s">%3$s</ul>',
'depth' => 0,
'walker' => ''
);

Il parametro theme_location imposta la posizione del menu, già registrata nel file functions.php con register_nav_menu, e gestita dal pannello di amministrazione (Aspetto → Menu).

Il parametro menu permette di associare manualmente il menu alla posizione stabilita in theme_location: se non impostato, questo viene gestito nel pannello di amministrazione.container imposta invece il contenitore della lista del menu: l'impostazione predefinita prevede una div, ma potrebbe essere un elemento nav o section, o essere anche del tutto assente.

Il parametro items_wrap imposta il contenitore dei singoli elementi, mentre depth stabilisce il numero di liste annidate possibili, ossia i livelli di sottomenu ammessi.

Il parametro walker, infine, imposta la classe che itera tra le voci del menu per generare l'output a video. Lasciando invariato il valore predefinito, la classe Walker_Nav_Menu genera le singole voci così come create dall'amministratore.

Un semplice esempio: un menu di navigazione personalizzato

Se il "Custom Menu"è stato correttamente registrato nel file functions.php, potrà essere richiamato in qualsiasi parte del tema. Per un menu di navigazione, la funzione wp_nav_menu può essere invocata nel template header.php, come nella seguente istruzione:

<?php wp_nav_menu(
array( 'theme_location' => 'custom',
'container_class' =>'custom',
'menu_class' => 'nav-menu' ) ); ?>

In questo esempio, alla funzione vengono passati solo i parametri theme_location, container_class e menu_class. Viene generato, quindi, il seguente output:

<div class="custom">
<ul id="menu-main-menu" class="nav-menu">
<li id=" … " class="menu-item … ">
…
</ul>

Le proprietà avanzate dei menu

Le impostazioni predefinite di WordPress permettono di inserire una quantità limitata di dati, cioè quelli indispensabili alla struttura predefinita del menu di navigazione.

Figura 2. I campi predefiniti di un elemento del menu
I campi predefiniti di un elemento del menu

È, però, possibile aumentare i campi a disposizione, in modo da associare una maggiore quantità di informazioni ad ogni singola voce di menu. Nella scheda "Impostazioni schermata", infatti, si stabilisce cosa visualizzare nel pannello di amministrazione dei menu ("Aspetto → Menu").

Figura 3. Le impostazioni schermata del pannello di amministrazione dei menu
Le impostazioni schermata del pannello di amministrazione dei menu

Spuntando tutte le voci disponibili sarà possibile associare classi specifiche ai singoli elementi del menu, stabilire la relazione tra i link, la destinazione e la descrizione del collegamento.

Figura 4. Una voce di menu con tutti i campi disponibili
Una voce di menu con tutti i campi disponibili

WordPress offre, quindi, la possibilità di inserire i dati necessari a generare un menu complesso. Tuttavia, molti dei dati qui inseriti non vengono visualizzati. Un menu che si discosta dalla struttura predefinita, infatti, va riprogrammato estendendo la classe Walker.

Un esempio avanzato: la classe Walker e la struttura del menu

La classe Walker di WordPress è una classe astratta che itera tra gli elementi di una qualsiasi struttura in cui essi siano organizzati gerarchicamente, proprio come avviene in un menu.

Per generare un menu di navigazione, WordPress dispone della classe Walker_Nav_Menu, che di per sé è già un'estensione di Walker. Estendendo quest'ultima classe, diventa possibile modificare la struttura del menu principale, o crearne di nuovi.
La classe Walker dispone di quattro metodi astratti che devono essere definiti nelle sue estensioni:

Metodo Descrizione
start_lvl apre il tag che definisce il contenitore del menu (es. <ul>);
end_lvl chiude il tag aperto da start_lvl (es. </ul>);
start_el apre il tag che individua il singolo elemento del menu (es. <li>);
end_el chiude il tag precedente (es. </li>);

Per modificare la struttura del "Custom menu"; bisogna, quindi, estendere la classe Walker_Nav_Menu e ridefinire i suoi metodi (la classe è definita nel file nav-menu-template.php, presente nella directory wp-includes).

Una semplice modifica alla struttura potrebbe essere quella dell'aggiunta della descrizione degli elementi di primo livello. Per effettuare questa modifica bisognerà definire una nuova classe che estenda Walker_Nav_Menu e ridefinisca il metodo start_el. Nel file functions.php del tema (o del child theme) si dovrà aggiungere il seguente codice:

class custom_walker extends Walker_Nav_Menu{
function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
$indent = ( $depth ) ? str_repeat( "t", $depth ) : '';
$class_names = $value = '';
$classes = empty( $item->classes ) ? array() : (array) $item->classes;
$classes[] = 'menu-item-' . $item->ID;
$class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args ) );
$class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : '';
$id = apply_filters( 'nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args );
$id = $id ? ' id="' . esc_attr( $id ) . '"' : '';
$output .= $indent . '<li' . $id . $value . $class_names .'>';
$atts = array();
$atts['title'] = ! empty( $item->attr_title ) ? $item->attr_title : '';
$atts['target'] = ! empty( $item->target ) ? $item->target : '';
$atts['rel'] = ! empty( $item->xfn ) ? $item->xfn : '';
$atts['href'] = ! empty( $item->url ) ? $item->url : '';
$atts = apply_filters( 'nav_menu_link_attributes', $atts, $item, $args );
$attributes = '';
foreach ( $atts as $attr => $value ) {
if ( ! empty( $value ) ) {
$value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr( $value );
$attributes .= ' ' . $attr . '="' . $value . '"';
}
}
/** Memorizza la descrizione dell'elemento del menu nella variabile $description */
$description = ! empty( $item->description ) ? '<span class="item-description">'.esc_attr( $item->description ).'</span>' : '';
if( $depth != 0 ){
$description = "";
}
$item_output = $args->before;
$item_output .= '<a'. $attributes .'>';
/** This filter is documented in wp-includes/post-template.php */
/** aggiunge il valore di $description prima della chiusura del tag <a> */
$item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $description . $args->link_after;
$item_output .= '</a>';
$item_output .= $args->after;
$output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
}
}

Confrontando questo listato con quello presente nel file nav-menu-template.php, si noterà che è stata instanziata una nuova variabile, $description. Questa terrà in memoria una stringa composta dal tag <span> e dalla descrizione della voce di menu inserita dall'amministratore. Nel file header.php andrà aggiunto alla funzione wp_nav_menu il parametro walker:

<?php wp_nav_menu( array(
'theme_location' => 'custom',
'container_class' =>'custom',
'menu_class' => 'nav-menu',
'walker' => new custom_walker() ) ); ?>

Rimane da dare uno stile all'elemento span.item-description nel foglio di stile del tema:

.item-description{
display: block;
padding-top: 6px;
font-style: italics;
font-size: small;
}

Figura 5. Il menu di navigazione del tema TwentyThirteen con la descrizione della prima voce di menu
Il menu di navigazione del tema TwentyThirteen con la descrizione della prima voce di menu

La descrizione verrà visualizzata al di sotto dell'etichetta degli elementi di primo livello.

Riferimenti online

Dunque estendendo la classe Walker è possibile apportare ogni tipo di modifica alla struttura predefinita dei menu. Il riferimento obbligato per approfondire l'argomento è il codex di wordpress.org. Da qui si potranno agevolmente raggiungere tutte le risorse cui si è fatto riferimento in questo articolo.

Il codice completo è disponibile in allegato all'articolo.

Ti consigliamo anche