Agregar la primera y la última clase al Menú en el nivel superior solamente

2

Estoy usando un Menú de WordPress para crear una navegación estructurada como esta:

  • Inicio
  • Acerca de
  • contacto
    • Subpágina

Usando este código de La respuesta de kuroi aquí Puedo agregar las clases first-menu-item y last-menu-item a los elementos de la lista anterior:

function add_first_and_last($output) {
    $output = preg_replace('/class="menu-item/', 'class="first-menu-item menu-item', $output, 1);
    $output = substr_replace($output, 'class="last-menu-item menu-item', strripos($output, 'class="menu-item'), strlen('class="menu-item'));
    return $output;
}
add_filter('wp_nav_menu', 'add_first_and_last');

Sin embargo, la clase last-menu-item se agrega al elemento de la lista de Subpáginas (porque es el último) en lugar de al elemento de la lista de contactos.

Pregunta: ¿Cómo puedo hacer que esta función se aplique solo a los elementos de nivel superior de un menú?

¡Gracias!

    
pregunta AlecRust 26.05.2013 - 15:01

4 respuestas

2

Me inclinaría mucho hacia un andador personalizado para esto, pero creo que logré que funcionara usando parte de ese código y parte del mío.

function add_position_classes_wpse_100781($classes, $item, $args) {
  static $fl;
  if (0 == $item->menu_item_parent) {
    $fl = (empty($fl)) ? 'first' : 'middle';
    $classes[] = $fl.'-menu-item';
  } 
  return $classes;
}
add_filter('nav_menu_css_class','add_position_classes_wpse_100781',1,3);

function replace_class_on_last_occurance_wpse_100781($output) {
    $output = substr_replace(
      $output, 
      'last-menu-item ', 
      strripos($output, 'middle-menu-item'), 
      strlen('middle-menu-item')
    );
    return $output;
}
add_filter('wp_nav_menu', 'replace_class_on_last_occurance_wpse_100781');

Lo que hice fue agregar first-menu-item y middle-menu-item a los elementos de nivel superior solo con el primer filtro en nav_menu_css_class . Luego, con el segundo filtro, reemplacé la última aparición de middle-menu-item con last-menu-item .

Funciona para los pocos casos de prueba que probé.

    
respondido por el s_ha_dum 26.05.2013 - 16:08
2

Tengo poca corrección en el código de Bainternet, porque este código no funciona si el último elemento tiene un subelemento

function wpb_first_and_last_menu_class($items) {
    $items[1]->classes[] = 'first-menu-item'; // add first class

    $cnt = count($items);
    while($items[$cnt--]->post_parent != 0); // find last li item
    $items[$cnt+1]->classes[] = 'last-menu-item'; // last item class
    return $items;
}
add_filter('wp_nav_menu_objects', 'wpb_first_and_last_menu_class'); //filter to iterate each menu
    
respondido por el Hitesh Siddhapura 15.06.2013 - 13:03
0

algo como esto:

function add_first_and_last_classes_wpa100781($items) {
    $items[1]->classes[] = 'first';
    $items[count($items)]->classes[] = 'last';
    return $items;
}

add_filter('wp_nav_menu_objects', 'add_first_and_last_classes_wpa100781');
    
respondido por el Bainternet 26.05.2013 - 16:11
0

Yo recomendaría:

1) omite la adición de la primera clase de elemento de menú . Eso es php extra que no necesitas. El uso de ul > li:first-child le permitirá apuntar al primer elemento del menú en CSS o como un selector jQuery. :first-child tiene una gran compatibilidad con el navegador (más que: último hijo, así que agregaría una clase para el último elemento del menú).

2) Encuentre el último elemento de menú de nivel superior y agregue una clase. Coloque este código en el archivo functions.php de su tema y agregará una clase. solo para el último elemento de navegación de nivel superior en lugar del último elemento de navegación como muchos de los fragmentos de código en las otras respuestas aquí.

// Add a class to the last top-level menu item
function fancy_last_menu_item_class($items) {
    // Create an empty array to hold the array ID's of top level menu items
    $topLevelMenuItemIDs = array();

    // Loop through all of the menu $items
    for($i=0,$count=count($items);$i<$count;$i++){
        // Check if the 'menu_item_parent' property is set to '0'
        if($items[$i]->menu_item_parent == 0){   
            // This item has no parent menu items, so it's top-level.
            // Add its array ID to the top level menu item IDs array.
            $topLevelMenuItemIDs[] = $i;
        }
    }

    // Count how many top level nav items were found, so you can target the last one
    $topLevelMenuItemCount = count($topLevelMenuItemIDs);

    // Add a class to the last top level navigation item.
    $lastMenuItemClass = 'last-menu-item';
    $items[$topLevelMenuItemIDs[--$topLevelMenuItemCount]]->classes[] = $lastMenuItemClass;

    // Return the items with the altered last item
    return $items;
}
// Hook the last menu item class to the wp_nav_menu_objects filter
add_filter('wp_nav_menu_objects', 'fancy_last_menu_item_class');
    
respondido por el Floyd 28.11.2015 - 04:25

Lea otras preguntas en las etiquetas