I'm using the code below in order to remove all classes but the current-menu-item and current-menu-parent classes from the custom menus.

It works very well, however, there's one nagging issue I'm trying to overcome. Some menu items end up with empty class attributes:

<ul id="menu-site-menu" class="menu">
    <li id="menu-item-18" class="current-menu-item "><a href="http://localhost/r23">Home</a></li>
    <li id="menu-item-19" class=""><a href="http://localhost/r23/about-us/">About Us</a></li>
    <li id="menu-item-20" class=""><a href="http://localhost/r23/contact-us/">Contact Us</a></li>

Its probably not that big a deal, but I'd rather not show a class attribute at all. Can this be done with minor revisions to the code below?

add_filter('nav_menu_css_class', 'clean_menu_classes', 10, 2);

function clean_menu_classes($classes, $item) {
    $classes = array_filter( 
        create_function( '$class', 
                 'return in_array( $class, 
                      array( "current-menu-item", "current-menu-parent" ) );' )
    return array_merge(
        (array)get_post_meta( $item->ID, '_menu_item_classes', true )

1 Answer 1


Unfortunately there is no filter which can overcome this issue. You have to override the start_el function of the walker. Here is the original source:

$class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args ) );
$class_names = ' class="' . esc_attr( $class_names ) . '"';

$id = apply_filters( 'nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args );
$id = strlen( $id ) ? ' id="' . esc_attr( $id ) . '"' : '';

$output .= $indent . '<li' . $id . $value . $class_names .'>';

As you can see, class is always appended, and it should be appended only if $classes is not empty

  • +1 Good catch Darhazer. I suppose it would be easy enough for a simple if/then to be added to the next WP update. How can I go about suggesting it or finding out if its already in the pipeline?
    – N2Mystic
    Commented Oct 24, 2011 at 14:13
  • @N2Mystic the requests and feedback for, I guess. Never submitted anything :) Commented Oct 24, 2011 at 14:16
  • @kaiser it applies filters BEFORE adding class="" string to them, and appending to the $output. In other words, filter is applied to the array of classes, but not to the generated output, which contains class="" Commented Oct 24, 2011 at 16:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.