¿Cómo puedo desactivar los enlaces de los elementos principales del menú?
No quiero que los elementos principales del menú de navegación de mi sitio enlacen a una página separada. Por un lado, no quiero tener una página superflua. Por otro, estos enlaces dificultan la navegación para usuarios móviles que no pueden "pasar el cursor" sobre un enlace (para mostrar los elementos hijos).
La mejor solución sería desactivar los enlaces de los elementos principales del menú. Pero, ¿cómo puedo hacer esto, especialmente ahora que con WordPress 3.5 el plugin Disable Parent Menu Item ha dejado de funcionar?
Una posible solución está aquí.

No crees URLs falsas (#
). Esto sería muy malo para usuarios con un lector de pantalla: ellos utilizan una lista de enlaces disponibles para navegar por tu sitio. Lo mismo aplica para enlaces javascript:
, no son exactamente un marcado elegante de todas formas.
Necesitas dos pasos:
- Marcar los elementos con hijos antes de que comience el walker.
- Reemplazar el marcado para los elementos padre principales.
Usaré un elemento <a>
vacío aquí para facilitar la obtención del cursor. Probablemente necesitarás algo como esto en tu hoja de estilos:
.menu > .has-children {
cursor: pointer;
}
El filtro para marcar los elementos padre está tomado de esta respuesta. La segunda función simplemente verifica esa propiedad y comprueba si el elemento no es en sí mismo un elemento hijo.
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 );
/**
* Añade la propiedad 'has_children' a los elementos del menú
*
* @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;
}
/**
* Reemplaza el marcado del elemento padre principal.
*
* @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 )
{
// no es un elemento padre de primer nivel
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";
}

Esta es una mejor respuesta que la mía, pero indica un fallo fundamental en los menús de WordPress: que se necesite tanto código para lograr algo que debería ser sencillo :)

@JCL1178 Supongo que no muchos autores usan un nivel superior sin href
. Y la mayoría de los temas personalizados usan un walker personalizado de todos modos. Veo la implementación nativa como una guía de inicio que funciona en la mayoría de los casos, pero no se impone al desarrollador.

Gracias por tu extensa respuesta, toscho. Veo que le has dedicado mucho trabajo. En realidad, la respuesta en el enlace que publiqué dice eliminar el símbolo de hash, por lo que no hay un símbolo de hash en el enlace que aparece en el menú: se convierte en un enlace sin un href
, es decir, sin URL, falsa o de otro tipo. Como tu solución parece depender de vaciar el href
también, me pregunto cómo es mejor para los lectores de pantalla. ¿Vale la pena tu walker?

@JohnK El plugin de ese hilo es probablemente el peor intento posible para resolver ese problema. Definitivamente tendrás conflictos con otros plugins porque llama a wp_print_scripts
por segunda vez. Esto nunca debería haber pasado la revisión de plugins… En fin, usa la solución PHP aquí; está libre de efectos secundarios, excepto cuando usas un plugin que trae su propio walker personalizado.

El enlace no era al plugin, toscho, sino a una forma simple y manual de reemplazarlo para crear un elemento de menú no clickeable. Parece producir el mismo efecto que tu código. Me gustaría darte crédito por tu trabajo, pero solo puedo elegir el tuyo como la respuesta correcta si de alguna manera justificas su superioridad sobre la forma simple.

Buena respuesta, y una solución mucho mejor que usar el símbolo de almohadilla como enlace como se indica en el enlace del publicador.

En realidad, si lees con cuidado, esa solución dice que hay que eliminar el símbolo de almohadilla, así que no hay ningún símbolo de almohadilla en el enlace.
