Aggiunta di prime / ultime classi CSS ai menu


15

è possibile, senza hack javascript? come questo:

<ul class="my_menu">
  <li class="first"> ... </li>
  <li> ... </li>
  <li> ... </li>
  <li class"with_sub"> ... 
    <ul class="my_menu_sub">
      <li class="first"> ... </li>
      <li> ... </li>
      <li> ... </li>
      <li class="last"> ... </li>
    </ul>
  </li>
  <li> ... </li>
  <li> ... </li>
  <li class="last"> ... </li>
</ul>

1
cosa c'è di sbagliato nell'uso di javascript? sono le funzionalità principali per cui sono? O potrebbe essere visto come un miglioramento progressivo?
Dolce Fuzz,

Risposte:


14

Un approccio migliore e più semplice:

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

add_filter('wp_nav_menu_objects', 'add_first_and_last');

1
Bello e semplice. Mi piace!
Jonathan Wold,

Vedo che questo codice funziona per i menu di navigazione personalizzati (l'ho visto funzionare in un widget di menu personalizzato), ma non funziona nello stesso menu utilizzato nella barra di navigazione principale (testato in Twenty Eleven). Dovrebbe essere? o sarebbe un codice diverso? o solo un filtro diverso? Grazie!
Evan Mattson,

2
Funzionerà per menu a livello singolo, ma potrebbe non essere più complesso perché a questo punto è un array con tutti gli elementi, non quelli di livello superiore.
Rarst

6

Ecco uno snippet di massima che si occupa della modifica dell'output del menu e dell'aggiunta del primo / ultimo alla prima e all'ultima classe (l'esterno ulnon viene applicato in questa fase, quindi non conta). Nota: richiede PHP5 perstrripos()

add_filter( 'wp_nav_menu_items', 'first_last_class' );

function first_last_class( $items ) {

    $first = strpos( $items, 'class=' );

    if( false !== $first )
         $items = substr_replace( $items, 'first ', $first+7, 0 );

    $last = strripos( $items, 'class=');

    if( false !== $last )
         $items = substr_replace( $items, 'last ', $last+7, 0 );

    return $items;
}

Sono un po 'bloccato con come farlo gestire elenchi nidificati, ma dovrebbe almeno iniziare.


6

Ecco una funzione per aggiungere solo la prima / ultima classe alle voci del menu principale. Per la maggior parte dello stile CSS, questo è tutto ciò che è necessario.

function nav_menu_add_classes( $items, $args ) {
    //Add first item class
    $items[1]->classes[] = 'menu-item-first';

    //Add last item class
    $i = count($items);
    while($items[$i]->menu_item_parent != 0 && $i > 0) {
        $i--;
    }
    $items[$i]->classes[] = 'menu-item-last';

    return $items;
}
add_filter( 'wp_nav_menu_objects', 'nav_menu_add_classes', 10, 2 );

1
esattamente quello che stavo cercando. Grazie. è abbastanza sorprendente che wp_nav_menu non lo faccia automaticamente
yitwail

Sono d'accordo. Credo che ci sia stata una richiesta di funzionalità nel bugtracker di Wordpress per un po ', ma non ne è venuto fuori nulla. Esistono almeno i filtri appropriati in modo da poter aggiungere queste classi;).
Chaoix,

1
Grazie. Stavo cercando il bancone, che poteva essere utilizzato nel menu walker. la tua risposta lo consente. Ho appena aggiunto $ item-> number = $ i; e l'ho preso nel walker. Grazie!!!
BasTaller

5

Ulteriori informazioni sulla nuova API dei menu in wordpress 3. Puoi assegnare manualmente a qualsiasi elemento la propria classe. Inoltre, una volta masterizzato, rende i menu una cosa piacevole da modificare.


2
Questo sarebbe il modo di procedere, basta aprire la schermata del menu di navigazione nell'amministratore e aggiungere una classe al primo e all'ultimo elemento. Naturalmente se l'utente sposta queste voci di menu, le classi dovranno essere riassegnate, ma ritengo sia la risposta più valida / migliore (perché non è prevista alcuna codifica).
t31os,

5

Se hai menu nidificati

function add_first_and_last($items) {
    // first class on parent most level
    $items[1]->classes[] = 'first';
    // separate parents and children
    $parents = $children = array();
    foreach($items as $k => $item){
        if($item->menu_item_parent == '0'){
            $parents[] = $k;
        } else {
            $children[$item->menu_item_parent] = $k;
        }
    }
    // last class on parent most level
    $last = end(array_keys($parents));
    foreach ($parents as $k => $parent) {
        if ($k == $last) {
            $items[$parent]->classes[] = 'last';
        }
    }
    // last class on children levels
    foreach($children as $child){
        $items[$child]->classes[] = 'last';
    }
    // first class on children levels
    $r_items = array_reverse($items, true);
    foreach($r_items as $k => $item){
        if($item->menu_item_parent !== '0'){
            $children[$item->menu_item_parent] = $k;
        }
    }
    foreach($children as $child){
        $items[$child]->classes[] = 'first';
    }
    return $items;
}
add_filter('wp_nav_menu_objects', 'add_first_and_last');

Mi piace la semplicità della risposta di Ismaelj, ma c'è bisogno di più se si vogliono lezioni di sottomenu.


2

Se non hai bisogno di supporto per IE8 o inferiore, non dimenticare che puoi anche usare CSS puro:

.my_menu > :first-child,
.my_menu > :last-child {
    /* some styles */
}

Il supporto del browser jQuery è ancora migliore, ma sembra che tu stia cercando di evitarlo.


Lo sto usando, perché last-child ora è supportato anche da IE 9 e non mi interessa più così tanto di 8, 7 ..
Alex

2

Ecco un codice migliore per l'aggiunta di classi di voci di menu primo e ultimo che include il supporto per i sottomenu nidificati.

add_filter( 'wp_nav_menu_objects', 'tgm_filter_menu_class', 10, 2 );
/**
 * Filters the first and last nav menu objects in your menus
 * to add custom classes.
 *
 * This also supports nested menus.
 *
 * @since 1.0.0
 *
 * @param array $objects An array of nav menu objects
 * @param object $args Nav menu object args
 * @return object $objects Amended array of nav menu objects with new class
 */
function tgm_filter_menu_class( $objects, $args ) {

    // Add first/last classes to nested menu items
    $ids        = array();
    $parent_ids = array();
    $top_ids    = array();
    foreach ( $objects as $i => $object ) {
        // If there is no menu item parent, store the ID and skip over the object
        if ( 0 == $object->menu_item_parent ) {
            $top_ids[$i] = $object;
            continue;
        }

        // Add first item class to nested menus
        if ( ! in_array( $object->menu_item_parent, $ids ) ) {
            $objects[$i]->classes[] = 'first-menu-item';
            $ids[]          = $object->menu_item_parent;
        }

        // If we have just added the first menu item class, skip over adding the ID
        if ( in_array( 'first-menu-item', $object->classes ) )
            continue;

        // Store the menu parent IDs in an array
        $parent_ids[$i] = $object->menu_item_parent;
    }

    // Remove any duplicate values and pull out the last menu item
    $sanitized_parent_ids = array_unique( array_reverse( $parent_ids, true ) );

    // Loop through the IDs and add the last menu item class to the appropriate objects
    foreach ( $sanitized_parent_ids as $i => $id )
        $objects[$i]->classes[] = 'last-menu-item';

    // Finish it off by adding classes to the top level menu items
    $objects[1]->classes[] = 'first-menu-item'; // We can be assured 1 will be the first item in the menu :-)
    $objects[end( array_keys( $top_ids ) )]->classes[] = 'last-menu-item';

    // Return the menu objects
    return $objects;

}

Puoi trovare l'essenza qui e il tutorial associato qui .



0

CSS puro, funziona per me. Funzionerà anche con i sottomenu

ul.nav>li:last-of-type a

solo in IE9 e versioni successive, il che lo esclude praticamente per tutto quello che faccio :)
Milo,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.