est-ce possible, sans piratage javascript? comme ça:
<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>
Une approche meilleure et plus simple:
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');
Voici une fonction permettant d’ajouter uniquement les première/dernière classes aux éléments de menu parent. Pour la plupart des styles CSS, c'est tout ce qui est nécessaire.
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 );
Voici un extrait de code qui prend en charge la modification de la sortie du menu et l’ajout du premier/dernier au premier et du dernier cours (la variable ul
extérieure n’est pas appliquée à ce stade, elle ne compte donc pas). Note - nécessite PHP5 pour strripos()
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;
}
Je suis un peu coincé avec la façon de le faire gérer les listes imbriquées, mais cela devrait au moins vous aider à démarrer.
Si vous avez des menus imbriqués
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');
J'aime la simplicité de la réponse d'Ismaelj, mais il doit y en avoir davantage si vous voulez des classes de sous-menus.
En savoir plus sur la nouvelle API de menus in wordpress 3. Vous pouvez attribuer manuellement à chaque élément sa propre classe. De plus, une fois maîtrisés, les menus deviennent un plaisir à éditer.
Voici un meilleur code pour l’ajout des première et dernière classes d’éléments de menu incluant la prise en charge des sous-menus imbriqués.
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;
}
Vous pouvez trouver le Gist ici et le tutoriel associé ici .
Si vous n'avez pas besoin de support pour IE8 ou une version antérieure, n'oubliez pas que vous pouvez également utiliser du CSS pur:
.my_menu > :first-child,
.my_menu > :last-child {
/* some styles */
}
la prise en charge du navigateur jQuery est encore meilleure, mais on dirait que vous essayez de l'éviter.
Pure CSS, fonctionne pour moi. Cela fonctionnera aussi avec les sous-menus
ul.nav>li:last-of-type a
Que diriez-vous:
ul li:last-child{
// do something with the last li
}
et peut-être quelques http://selectivizr.com/