Problem with empty class attributes when running a filter on nav_menu_css_class

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:

Read More
<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>
</ul>

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( 
        $classes, 
        create_function( '$class', 
                 'return in_array( $class, 
                      array( "current-menu-item", "current-menu-parent" ) );' )
        );
    return array_merge(
        $classes,
        (array)get_post_meta( $item->ID, '_menu_item_classes', true )
        );
    }

Related posts

Leave a Reply

1 comment

  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