2

Is there a good way to add a class of "parent" to list items that have children using wp_nav_menu?

I've found a couple of solutions online but non seem to have the desired effect.

0

This may not be the ideal solution, depending on what you need the class for, but you could add a "parent" class via JavaScript. The line below uses the jQuery :has() selector:

$('#nav-id').find('li:has(ul)').addClass('parent');
3

See Wordpress codex http://codex.wordpress.org/Function_Reference/wp_nav_menu#How_to_add_a_parent_class_for_menu_item

Use this function:

add_filter('wp_nav_menu_objects', function ($items) {
    $hasSub = function ($menu_item_id, &$items) {
        foreach ($items as $item) {
            if ($item->menu_item_parent && $item->menu_item_parent==$menu_item_id) {
                return true;
            }
        }
        return false;
    };

    foreach ($items as &$item) {
        if ($hasSub($item->ID, &$items)) {
            $item->classes[] = 'menu-parent-item'; // all elements of field "classes" of a menu item get join together and render to class attribute of 
  • element in HTML } } return $items; });
    1

    You can do it with a bit of regex and a custom menu walker although I've not tested this thoroughly:

    class My_Walker_Nav_Menu extends Walker_Nav_Menu {
        function start_lvl(&$output, $depth) {
            $indent = str_repeat("\t", $depth);
            $output = preg_replace( "/(.*)(\<li.*?class\=\")([^\"]*)(\".*?)$/", "$1$2$3 has-submenu$4", $output );
            $output .= "\n$indent<ul class=\"sub-menu\">\n";
        }
    }
    

    What this does is every time we start a new level within the menu we look at the last opening <li> in the string and add 'has-submenu' to the class attribute. Unfortunately at the time of generating the list item itself we don't know if it has children or not.

    To use the above just pass in the walker argument where you declare your menu eg:

    wp_nav_menu( array( 'theme_location' => 'header', 'walker' => new My_Walker_Nav_Menu() ) );
    

    Your Answer

    By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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