Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

Any help would be much appreciated.

like image 692
Ali Avatar asked Jan 12 '23 16:01

Ali


1 Answers

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 :)

like image 180
Sovit Tamrakar Avatar answered Jan 14 '23 06:01

Sovit Tamrakar