Sometimes you want to be able to style your first and/or last menu items
differently from the rest. Maybe you want to remove padding, shift
margins, or the like.
The code snippet below will apply the classes to all menus on your site( add in function.php file of your theme):
add_filter( 'wp_nav_menu_objects', 'tgm_filter_menu_class' );
function tgm_filter_menu_class( $objects ) {
// Add "first-menu-item" class to the first menu object
$objects[1]->classes[] = 'first-menu-item';
// Add "last-menu-item" class to the last menu object
$objects[count( $objects )]->classes[] = 'last-menu-item';
// Return the menu objects
return $objects;
}
If you want to go a step further and limit this to only a particular navigation menu on your site,
check out the code below:
add_filter( 'wp_nav_menu_objects', 'tgm_filter_menu_class', 10, 2 );
function tgm_filter_menu_class( $objects, $args ) {
// Only apply the classes to the primary navigation menu
if ( isset( $args->theme_location ) )
if ( 'primary' !== $args->theme_location )
return $objects;
// Add "first-menu-item" class to the first menu object
$objects[1]->classes[] = 'first-menu-item';
// Add "last-menu-item" class to the last menu object
$objects[count( $objects )]->classes[] = 'last-menu-item';
// Return the menu objects
return $objects;
}
Now if you have noticed above, these two pieces of code are really only effective for top level menus (e.g. menus with no dropdowns).
If you want to add the same class structure to nested menus,use the code below. It will do the exact same thing as above,except for it will apply the
logic to all nested submenus in your menu structure.
add_filter( 'wp_nav_menu_objects', 'tgm_filter_menu_class', 10, 2 );
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;
}
No comments:
Post a Comment