WordPress – Maintain “active” class on parent menu item

I am implementing a theme in WordPress. This theme has a top navigation menu with horizontal sub menus under each parent item. It puts an “active” class on current parent items currently been viewed (otherwise it won’t show it’s children sub menu items). I have somehow managed to maintain “active” class on current parent items by using these two function in functions.php.

/**
 * Wp Nav Menu Customizer.
 */
function special_nav_class($classes, $item){
     if( in_array('current-menu-item', $classes) ){
             $classes[] = 'active ';
     }
     return $classes;
}
add_filter('nav_menu_css_class' , 'special_nav_class' , 10 , 2);


class SH_Last_Walker extends Walker_Nav_Menu{

   function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output ) {

        $id_field = $this->db_fields['id'];

       //If the current element has children, add class 'sub-menu'
       if( isset($children_elements[$element->$id_field]) ) { 
            $classes = empty( $element->classes ) ? array() : (array) $element->classes;
            $classes[] = 'has-sub-menu';
            $element->classes =$classes;
       }
        // We don't want to do anything at the 'top level'.
        if( 0 == $depth )
            return parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );

        //Get the siblings of the current element
        $parent_id_field = $this->db_fields['parent'];      
        $parent_id = $element->$parent_id_field;
        $siblings = $children_elements[ $parent_id ] ;

        //No Siblings?? 
        if( ! is_array($siblings) )
            return parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );

        //Get the 'last' of the siblings.
        $last_child = array_pop($siblings);
        $id_field = $this->db_fields['id'];

            //If current element is the last of the siblings, add class 'last'
        if( $element->$id_field == $last_child->$id_field ){
            $classes = empty( $element->classes ) ? array() : (array) $element->classes;
            $classes[] = 'last';
            $element->classes =$classes;
        }

        return parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );
    }
}

But now my problem is that when i click on sub menu or child of any parent menu item it successfully takes me to the child page but removes “active” class from parent and puts it on children (because it is the currently viewed page). I don’t want it to put this class to children, i want it to be there (on parent item) whenever it’s children are being viewed.

Read More

Any help would be much appreciated.

Related posts

Leave a Reply

3 comments

  1. if you want to the dropdown grand-grand parent to be active when child menu item is active, then you can check for current-menu-ancestor or current-page-ancestor.. in your case, i think current-menu-ancestor check is most favorable.

    function special_nav_class($classes, $item){
         if( in_array('current-menu-item', $classes) || in_array('current-menu-ancestor', $classes) ){
                 $classes[] = 'active ';
         }
         return $classes;
    }
    

    I hope this would help, have a nice day 🙂

  2. If all you want is to add some style or other properties by targeting the parent element then WordPress Provides you built-in classes for it for example:

    when you are on a child page you can see classes like current-menu-parent current-page-parent current_page_parent current_page_ancestor these added to the parent page by WordPress you can choose any of these to target the parent element.

  3. When you click on sub menu item WordPress will add .current-menu-item class to that sub menu item and .current-menu-parent class to the parent menu item of that sub menu item. You can style those specific classes according to your needs.