Menülere ilk / son CSS sınıflarını ekleme


15

Javascript kesmek olmadan bu mümkün mü? bunun gibi:

<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
javascript kullanımıyla ilgili sorun nedir? temel işlevleri bunlar için mi? Yoksa aşamalı bir gelişme olarak görülebilir mi?
Hafif Fuzz

Yanıtlar:


14

Daha iyi ve daha basit bir yaklaşım:

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
Güzel ve basit. Bunu sevdim!
Jonathan Wold

Bu kodun özel gezinme menüleri için çalıştığını görüyorum (özel menü widget'ında çalıştığını gördüm), ancak birincil gezinme çubuğunda (Yirmi Onbir'de test edilmiş) kullanılan aynı menüde çalışmıyor. Olmalı mı? yoksa bu farklı bir kod olabilir mi? veya sadece farklı bir filtre? Teşekkürler!
Evan Mattson

2
Bu tek seviyeli menü için çalışacaktır, ancak daha karmaşık bir menü için çalışmayabilir, çünkü bu noktada en üst düzey olanları değil, tüm öğeleri içeren bir dizi.
Rarst

6

Burada menü çıktısını değiştirme ve ilk / sondan birinci ve son sınıfa ekleme yapan kaba snippet ( ulbu aşamada dış uygulanmaz, bu nedenle sayılmaz). Not - için PHP5 gerektirirstrripos()

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;
}

Ben iç içe listeleri işlemek için nasıl sıkışmış, ama en azından başlamanız gerekir.


6

Burada üst menü öğelerine yalnızca ilk / son sınıfları eklemek için bir işlev verilmiştir. Çoğu CSS stili için gerekli olan tek şey budur.

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
tam olarak aradığım şey. Teşekkürler. şaşırtıcı bir şekilde wp_nav_menu bunu otomatik olarak yapmaz
yitwail

Katılıyorum. Bir süre Wordpress bugtracker'da bir özellik isteği olduğuna inanıyorum, ancak hiçbir şey gelmedi. En azından uygun filtreler var, böylece bu sınıfları ekleyebiliriz;).
Chaoix

1
Teşekkürler. Menü yürüteç kullanılabilir sayacı, arıyordu. cevabınız buna izin veriyor. Yeni $ item-> number = $ i; ve yürüteç içine aldım. Teşekkürler!!!
BasTaller

5

Wordpress 3'teki yeni Menüler API'si hakkında daha fazla bilgi edinin . Kendi sınıfındaki herhangi bir öğeyi el ile verebilirsiniz. Ayrıca, bir kez hakim olduktan sonra, menüleri düzenlemek bir zevk haline getirir.


2
Bu gitmek için bir yol olacaktır, sadece yönetici menüsündeki nav menü ekranını açın ve ilk ve son öğelere bir sınıf ekleyin. Tabii ki kullanıcı bu menü öğelerini hareket ettirirse, sınıfların yeniden atanması gerekir, ancak bu en geçerli / en iyi yanıt olduğunu düşünüyorum (çünkü kodlama dahil değildir).
t31os

5

İç içe menüleriniz varsa

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');

Ismaelj'ın cevabının basitliğini seviyorum, ancak alt menü sınıfları istiyorsanız daha fazlası olmalı.


2

IE8 veya daha düşük sürümler için desteğe ihtiyacınız yoksa, saf CSS kullanabileceğinizi de unutmayın:

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

jQuery tarayıcı desteği daha da iyidir, ancak bundan kaçınmaya çalıştığınız anlaşılıyor.


Son-çocuk artık çok IE 9 tarafından desteklenen çünkü o kullanıyorum ve ben yani hakkında çok fazla artık umurumda değil 8, 7 ..
Alex

2

İç içe alt menüler için destek içeren ilk ve son menü öğesi sınıflarını eklemek için bazı daha iyi kodlar.

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;

}

Sen özünü bulabilirsiniz burada ve ilgili öğretici burada .



0

Saf CSS, benim için çalışıyor. Bu, alt menülerle de çalışacaktır

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

sadece IE9 ve üstü, yaptığım hemen hemen her şey için bunu dışlıyor :)
Milo
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.