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
    Oct 24, 2011 at 14:13
  • @N2Mystic the requests and feedback for, I guess. Never submitted anything :) 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="" Oct 24, 2011 at 16:39

Your Answer

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

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