Come disabilitare i link degli elementi genitore del menu?
Non voglio che gli elementi genitore dei menu di navigazione del mio sito puntino a pagine separate. Da un lato non voglio avere pagine superflue. Dall'altro questi link ostacolano la navigazione per gli utenti mobile che non possono "passare il mouse" su un link (per visualizzare gli elementi figlio).
La soluzione migliore sarebbe disabilitare i link degli elementi genitore del menu. Ma come posso farlo, specialmente ora che con WordPress 3.5 il plugin Disable Parent Menu Item ha smesso di funzionare?
Una possibile soluzione è disponibile qui.

Non creare URL falsi (#
). Questo sarebbe molto negativo per gli utenti che utilizzano uno screen reader: utilizzano un elenco di link disponibili per navigare il tuo sito. Lo stesso vale per i link javascript:
, che comunque non sono un markup particolarmente elegante.
Sono necessari due passaggi:
- Contrassegna gli elementi con figli prima che inizi il walker.
- Sostituisci il markup per i genitori di primo livello.
Utilizzerò un elemento <a>
vuoto qui per semplificare l'ottenimento del cursore. Probabilmente avrai bisogno di qualcosa come questo nel tuo foglio di stile:
.menu > .has-children {
cursor: pointer;
}
Il filtro per contrassegnare gli elementi genitori è tratto da questa risposta. La seconda funzione verifica semplicemente la presenza di quella proprietà e controlla se l'elemento stesso non è un elemento figlio.
add_filter( 'wp_nav_menu_objects', 't5_add_has_children_to_nav_items' );
add_filter( 'walker_nav_menu_start_el', 't5_unlink_parent_item', 10, 4 );
/**
* Aggiunge una proprietà 'has_children' agli elementi del menu
*
* @wp-hook wp_nav_menu_objects
* @param array $items
* @return array
*/
function t5_add_has_children_to_nav_items( $items )
{
$parents = wp_list_pluck( $items, 'menu_item_parent' );
$out = array ();
foreach ( $items as $item )
{
in_array( $item->ID, $parents ) && $item->has_children = TRUE;
$out[] = $item;
}
return $items;
}
/**
* Sostituisce il markup per gli elementi genitori di primo livello.
*
* @wp-hook walker_nav_menu_start_el
* @param string $item_output
* @param object $item
* @param int $depth
* @param object $args
* @return string
*/
function t5_unlink_parent_item( $item_output, $item, $depth, $args )
{
// non è un elemento genitore di primo livello
if ( empty ( $item->has_children ) or 0 != $item->menu_item_parent )
return $item_output;
$title = apply_filters(
'the_title',
$item->title,
$item->ID
);
$id = apply_filters(
'nav_menu_item_id',
'menu-item-'. $item->ID,
$item, $args
);
$id = $id ? ' id="' . esc_attr( $id ) . '"' : '';
$classes = empty( $item->classes ) ? array() : (array) $item->classes;
$classes[] = 'menu-item-' . $item->ID;
$classes[] = 'has-children';
$class_names = join(
' ',
apply_filters(
'nav_menu_css_class',
array_filter( $classes ),
$item,
$args
)
);
$class_names = $class_names
? ' class="' . esc_attr( $class_names ) . '"'
: '';
return "<li$id>$args->before<a class='menu-item has-children'>$title</a>$args->after";
}

Questa è una risposta migliore della mia, ma indica un difetto fondamentale nei menu di WordPress: è necessario tutto questo codice per ottenere ciò che dovrebbe essere una cosa semplice :)

@JCL1178 Immagino che non molti autori utilizzino un livello superiore senza href
. E la maggior parte dei temi personalizzati utilizza comunque un walker personalizzato. Vedo l'implementazione nativa come una guida iniziale che funziona nella maggior parte dei casi ma non è imposta agli sviluppatori.

Grazie per la tua risposta dettagliata, toscho. Si vede che ci hai messo molto impegno. In realtà, la risposta nel link che ho postato dice di rimuovere il simbolo del cancelletto, quindi non c'è alcun cancelletto nel link che appare nel menu: diventa un link senza un href
, cioè senza URL, falso o meno. Dato che la tua soluzione sembra dipendere dall'evacuazione anche dell'href
, mi chiedo come sia migliore per i lettori di schermo. Vale la pena usare il tuo walker?

@JohnK Il plugin di quel thread è probabilmente il tentativo peggiore possibile per risolvere quel problema. Avrai sicuramente conflitti con altri plugin, perché chiama wp_print_scripts
una seconda volta. Questo non avrebbe mai dovuto superare la revisione dei plugin... Comunque, usa la soluzione PHP qui; è priva di effetti collaterali, a meno che non utilizzi un plugin che include il suo walker personalizzato.

Il link non era al plug-in, toscho, ma a un modo semplice e "manuale" per sostituirlo creando una voce di menu non cliccabile. Sembra produrre lo stesso effetto del tuo codice. Vorrei darti credito per il tuo lavoro, ma posso scegliere la tua come risposta corretta solo se in qualche modo giustifichi la sua superiorità rispetto al metodo semplice.

Buona risposta, e una soluzione molto migliore rispetto all'uso del simbolo del cancelletto come link come indicato nel link del poster.

In realtà, se leggi attentamente, quella soluzione dice di rimuovere il simbolo del cancelletto, quindi non c'è alcun simbolo di cancelletto nel link.
