• Hi, all,
    is it possible to filter menu so that only expanded branch is the one where current item is located?
    E.g., I have menu like this:

    AAA
      aaa
        111
        222
      bbb
        111
      ccc
    BBB
      aaa
    CCC

    When my active item is “111”, I would like to have visible all top level items, but expanded only the branch where the active item is:

    AAA <- siblings of parent visible
      aaa <- siblings of parent visible
        111 <- current
        222 <- sibling visible
      bbb <- not expanded
      ccc
    BBB <- not expanded, visible!
    CCC <- not expanded, visible!

    So the algorithm would be something like:

    {
     1. Display siblings of current item.
     2. Get parent item.
    } Repeat until parent item not found

    Can this be achieved somehow?
    Thx in advance.

Viewing 1 replies (of 1 total)
  • sgmurphy19

    (@sgmurphy19)

    Thanks oorafal for your response in the other thread. I’m replying here since this is a more general forum thread instead of one under a specific plugin.
    I ended up doing something similar but on the server side by creating my own menu widget plugin. I iterate through the selected menu and add a hidden class to all the menu-items which either do not have the current page as its menu_item_parent or do not have a menu_item_parent matching any of the current page’s ancestors.
    It’s just one PHP file. Here is the full code if it helps anyone else out in the future.

    <?php
    /*
    Plugin Name: OSN Pages Menu
    Plugin URI: https://www.opensciencenetwork.org/
    Description: A simple widget to display the side menu for the OSN website
    Version: 1.0
    Author: Sean Murphy
    Author URI: https://www.betterourtomorrow.com/
    License: GPL2
    */
    class OSN_Pages_Menu extends WP_Widget {
    
    	// constructor
    	function OSN_Pages_Menu() {
    		parent::WP_Widget(false, $name = __('OSN Pages Menu', 'OSN_Pages_Menu') );
    	}
    
    	// widget form creation
    	function form($instance) {
    		//get menus...
    		$menus = wp_get_nav_menus( array( 'orderby' => 'name' ) );
    		$noitems = true;
    		if( !empty( $menus ) ){
    			foreach( $menus as $i=>$menu ){
    				$menus[ $i ]->_items = wp_get_nav_menu_items( $menu->term_id );
    				if( !empty( $menus[ $i ]->_items ) ){
    					$noitems = false;
    				}
    			}
    		}
    
    		//no menus exist with items...
    		if( $noitems ){
    			echo '<p>'. sprintf( __('There are no populated menus. <a href="%s">Go to Menus</a>.'), admin_url('nav-menus.php') ) .'</p>';
    			return;
    		}
    ?>
    		<p>
    			<label for="<?php echo $this->get_field_id('menu'); ?>"><?php _e('Select Menu:'); ?></label>
    			<select id="<?php echo $this->get_field_id('menu'); ?>"
    					class="widget-<?php echo $this->id_base; ?>-selectmenu widget-<?php echo $this->id_base; ?>-listen"
    					name="<?php echo $this->get_field_name('menu'); ?>">
    <?php
    		foreach( $menus as $i=>$menu ){
    			if( !empty( $menu->_items ) ){
    ?>
    				<option <?php selected($instance['menu'], $menu->term_id); ?> value="<?php echo $menu->term_id; ?>"><?php echo $menu->name; ?></option>
    <?php
    			}
    		}
    ?>
    			</select>
    		</p>
    <?php
    	}
    
    	// widget update
    	function update($new_instance, $old_instance) {
    		$instance = $old_instance;
    		// Fields
    		$instance['menu'] = strip_tags($new_instance['menu']);
    		return $instance;
    	}
    
    	// widget display
    	function widget($args, $instance) {
    		extract( $args );
    		// create the widget...
    		if( !empty($instance['menu'] ) ){
    			$menu = wp_get_nav_menu_object( intval($instance['menu']) );
    			//no menu, no output...
    			if ( !empty( $menu ) ){
    
    				$items = wp_get_nav_menu_items( $menu->term_id, array( 'order' => 'DESC' ));
    				$item_arrays = (array)$items[0];
    
    				$this_menu_item_parent = -1;
    				$this_db_id = -1;
    				$top_db_id = $items[0]->db_id;//first menu item will always be a top parent
    				$top_menu_item_parent = $items[0]->menu_item_parent;//parent of first item will be the same parent of all top level item
    				$exclude_array = array();
    				foreach($items as $item) {
    					if($item->object_id == get_the_ID()) {
    						$this_menu_item_parent = $item->menu_item_parent;
    						$this_db_id = $item->db_id;
    					}
    					$exclude_array[] = $item->db_id; //adds all menu ids to the array to be removed later
    				}
    				if($this_menu_item_parent == -1) { //means there isn't a menu item for this page
    					$this_menu_item_parent = $top_menu_item_parent;
    					$this_db_id = $top_db_id;
    				}
    
    				echo $before_widget;
    				// Display the widget
    				echo '<div class="side_nav widget rounded_2">';
    
    				$next_menu_item_parent = $this_db_id;//this accounts for all the children of the current menu item
    				while($next_menu_item_parent != -1) {
    					$current_menu_item_parent = $next_menu_item_parent;
    					foreach($items as $item) {
    						if($item->db_id == $current_menu_item_parent) {
    							$next_menu_item_parent = $item->menu_item_parent;
    						}
    						if($item->menu_item_parent == $current_menu_item_parent) {
    							$exclude_array = array_diff($exclude_array, array($item->db_id));//removes the pages we want from the list of excluded pages
    						}
    					}
    					if($current_menu_item_parent == $top_menu_item_parent) {
    						$next_menu_item_parent = -1;
    					}
    				}
    				$menu = wp_nav_menu( array('menu' => intval($instance['menu']), 'echo' => 0 ));
    				foreach($exclude_array as $excluded_id) {
    					$menu = str_replace('menu-item-'.$excluded_id, 'menu-item-'.$excluded_id.' hidden', $menu);
    				}
    				echo $menu;
    
    				echo '</div>';
    				echo $after_widget;
    			}
    		}
    	}
    }
    
    // register widget
    add_action('widgets_init', create_function('', 'return register_widget("OSN_Pages_Menu");'));
    ?>

Viewing 1 replies (of 1 total)
  • The topic ‘Multilevel menu with only expanded current branch – how?’ is closed to new replies.