Skip to content

Instantly share code, notes, and snippets.

@thomasgriffin
Last active October 13, 2015 20:48
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thomasgriffin/4253962 to your computer and use it in GitHub Desktop.
Save thomasgriffin/4253962 to your computer and use it in GitHub Desktop.
<?php
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;
}
@bassscape
Copy link

Thanks for the filter, I have been using it for sometime now.

I just started getting the following error:
"Strict Standards: Only variables should be passed by reference on line 53".

The issue was resolved by replacing line 53:

$objects[end( array_keys( $top_ids ) )]->classes[] = 'last-menu-item';

with the following two lines:

$top_ids_array_keys = array_keys($top_ids);
$objects[end( $top_ids_array_keys )]->classes[] = 'last-menu-item';

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment