[Resolved] Multiple primary navigations?

Home Forums Support Multiple primary navigations?

Viewing 8 posts - 1 through 8 (of 8 total)
  • Author
    Posts
  • #200226
    Tommi

    Greetings, I have a bit of a hump coming up in the development of my project.

    What I’m after is following:
    A website that has 3 different navigations all taking the same exact spot and styling, but their contents change. Of course these navigations are exclusive to one another so at any given time the user sees only one navigation relevant to the site context he is in.

    Picture it as 3 different websites. Operating under single WordPress.

    So how would one modify GeneratePress to get the desired functionality?

    #200310
    Tom
    Lead Developer
    Lead Developer
    #200413
    Tommi

    Thank you for the quick response Tom.

    I’ll give both of the plugins a look run to see about their functionality. They may provide what I need. But in case these plugins don’t work with the already existing menu plugin on my site. Is it possible to modify / add new code to register new menu locations for GeneratePress based on the page you are in at the time? I’m not a stranger to Php. And If I can do it cleanly with code, I would prefer it to adding an ever increasing amount of plugins.

    #200425
    Tom
    Lead Developer
    Lead Developer

    That’s exactly what this plugin does: https://wordpress.org/plugins/menu-swapper/

    If you’d rather not use the plugin you can take a look at the code to see how they do it 🙂

    #200484
    Tommi

    Hello, just to report on my progress.

    I’ve managed to bend GeneratePress into changing the menus without any additional plugins. Here’s how:

    First and foremost. I have 3 navigation areas. Primary navigation has pages that are considered top level pages in hierarchy. Read more about it here: codex.wordpress.org. One of these pages we shall call “site-area-1” which is a parent or an ancestor to every page under that topic. This is crucial for the longer code below to work, without it the if statement won’t function as intended and the entire thing falls apart.

    all the code in this version is inserted into functions.php file in your child theme.

    Start by registering the new navigation menus. In my case I wanted the primary menu and two additional menus to be changed at will:

    
    register_nav_menus( array(
    	'site-area-1'       => __( 'menuName1', 'myChildTheme'),
    	'site-area-2'       => __( 'menuName2', 'myChildTheme)
    ) );
    

    Following this, and here is the rather rough part (It’ll probably need a lot of cleanup). We hijack the function “generate_navigation_position()” from themes/generatepress/inc/navigation.php and declare it like so:

    
    function generate_navigation_position()
    {
    	?>
    	<nav itemtype="http://schema.org/SiteNavigationElement" itemscope="itemscope" id="site-navigation" <?php generate_navigation_class(); ?>>
    		<div class="inside-navigation grid-container grid-parent">
    			<?php do_action( 'generate_inside_navigation' ); ?>
    			<button class="menu-toggle" aria-controls="primary-menu" aria-expanded="false">
    				<?php do_action( 'generate_inside_mobile_menu' ); ?>
    				<span class="mobile-menu"><?php echo apply_filters('generate_mobile_menu_label', __( 'Menu', 'generatepress' ) ); ?></span>
    			</button>
    			<?php 
    
    			/* Get current ID and get it's ancestors. */
    				global $post;
    				$ancs = get_ancestors($post->ID, 'page');
    				/*Ancestors returns an array. */
    
    				if( end($ancs) == 90 || is_page(90)) {
    					/* check value of array index 0 against ancestor's page ID */
    					wp_nav_menu( 
    						array( 
    							'theme_location' => 'site-area-1', 
    							/* Add registered menu to 'theme_location' => 'YOUR_MENU' */
    							'container' => 'div',
    							'container_class' => 'main-nav',
    							'container_id' => 'primary-menu',
    							'menu_class' => '',
    							'fallback_cb' => 'generate_menu_fallback',
    							'items_wrap' => '<ul id="%1$s" class="%2$s ' . join( ' ', generate_get_menu_class() ) . '">%3$s</ul>'
    						) 
    					);
    				} 
    
    				elseif( end($ancs) == 92 || is_page(92)) {
    
    					wp_nav_menu( 
    						array( 
    							'theme_location' => 'site-area-2',
    							'container' => 'div',
    							'container_class' => 'main-nav',
    							'container_id' => 'primary-menu',
    							'menu_class' => '',
    							'fallback_cb' => 'generate_menu_fallback',
    							'items_wrap' => '<ul id="%1$s" class="%2$s ' . join( ' ', generate_get_menu_class() ) . '">%3$s</ul>'
    						) 
    					);
    				}
    				else{
    					wp_nav_menu( 
    						array( 
    							'theme_location' => 'primary',
    							'container' => 'div',
    							'container_class' => 'main-nav',
    							'container_id' => 'primary-menu',
    							'menu_class' => '',
    							'fallback_cb' => 'generate_menu_fallback',
    							'items_wrap' => '<ul id="%1$s" class="%2$s ' . join( ' ', generate_get_menu_class() ) . '">%3$s</ul>'
    						) 
    					);
    			} 
    			?>
    		</div><!-- .inside-navigation -->
    	</nav><!-- #site-navigation jalla jalla -->
    	<?php
    }
    

    With this I got it to function. Every page that is a grand child of page ID 90 will get site-area-1 navigation and every page that is a grandchild of page ID 92 will get site-area-2 navigation. For pages that are neither they’ll get the primary menu from the Else segment.

    Known problems:
    Carets (down arrows for dropdowns) and search field do not function in site-area-1 and 2 navigations, yet.

    • This reply was modified 4 years, 3 months ago by Tommi. Reason: typos within the code
    • This reply was modified 4 years, 3 months ago by Tommi.
    #200576
    Tom
    Lead Developer
    Lead Developer

    Great job.

    You’ll see the reason carets aren’t working by inspecting the generate_nav_dropdown() function in navigation.php. There’s a check for theme locations in there.

    There’s no ! function_exists() call, which means you’ll have to remove_action that call, and then add your own.

    #200727
    Tommi

    Thank you for the help Tom, I’ve managed to build up all the functionality i’ve desired to the navigation. There are three primary navigations, each with their own carets and search fields. The mobile scaling works all built into the standard GeneratePress without plugins. All that remains is a truckload of css declarations to get this styled.

    In the end I didn’t use remove_action as suggested. The carets were applied with a wordpress filter hook. I used the same hook to add a function with a different name and values to just add the exact same functionality to the site-area-1 and 2 menus without touching the declaration on the primary-menu.

    For anyone else that is trying to achieve a similar changing navigation based on where in the site the user is. Here is the functioning code, be warned though I am still a junior web developer so there might be errors in the code.

    register_nav_menus( array(
    	'site-area-1'       => __( 'menuLocationName', 'myTheme'),
    	'site-area-2'       => __( 'menuLocationName', 'myTheme')
    ) );
    
    /** End register menu **/
    
    /** Start navigation **/
    /** Following function chooses and builds a navigation based on the location the user is in. **/
    
    function generate_navigation_position()
    {
    	?>
    	<nav itemtype="http://schema.org/SiteNavigationElement" itemscope="itemscope" id="site-navigation" <?php generate_navigation_class(); ?>>
    		<div class="inside-navigation grid-container grid-parent">
    			<?php do_action( 'generate_inside_navigation' ); ?>
    			<button class="menu-toggle" aria-controls="primary-menu" aria-expanded="false">
    				<?php do_action( 'generate_inside_mobile_menu' ); ?>
    				<span class="mobile-menu"><?php echo apply_filters('generate_mobile_menu_label', __( 'Menu', 'generatepress' ) ); ?></span>
    			</button>
    			<?php 
    
    			/* Get current ID and get it's ancestors. */
    				global $post;
    				$ancs = get_ancestors($post->ID, 'page');
    				/*Ancestors returns an array. */
    
    				if( end($ancs) == 90 || is_page(90)) {
    					/* check value of array's last index against ancestor's page ID */
    					wp_nav_menu( 
    						array( 
    							'theme_location' => 'site-area-1', 
    							/* Add registered menu to 'theme_location' => 'YOUR_MENU' */
    							'container' => 'div',
    							'container_class' => 'main-nav',
    							'container_id' => 'primary-menu',
    							'menu_class' => '',
    							'fallback_cb' => 'generate_menu_fallback',
    							'items_wrap' => '<ul id="%1$s" class="%2$s ' . join( ' ', generate_get_menu_class() ) . '">%3$s</ul>'
    						) 
    					);
    				} 
    
    				elseif( end($ancs) == 92 || is_page(92)) {
    
    					wp_nav_menu( 
    						array( 
    							'theme_location' => 'site-area-2',
    							'container' => 'div',
    							'container_class' => 'main-nav',
    							'container_id' => 'primary-menu',
    							'menu_class' => '',
    							'fallback_cb' => 'generate_menu_fallback',
    							'items_wrap' => '<ul id="%1$s" class="%2$s ' . join( ' ', generate_get_menu_class() ) . '">%3$s</ul>'
    						) 
    					);
    				}
    				else{
    					wp_nav_menu( 
    						array( 
    							'theme_location' => 'primary',
    							'container' => 'div',
    							'container_class' => 'main-nav',
    							'container_id' => 'primary-menu',
    							'menu_class' => '',
    							'fallback_cb' => 'generate_menu_fallback',
    							'items_wrap' => '<ul id="%1$s" class="%2$s ' . join( ' ', generate_get_menu_class() ) . '">%3$s</ul>'
    						) 
    					);
    			} 
    			?>
    		</div><!-- .inside-navigation -->
    	</nav><!-- #site-nav -->
    	<?php
    }
    /** End navigation **/
    
    /* Following function adds the down arrow to the navigation bars. Add new navigation menus into the if statement below. */
    
    add_filter( 'walker_nav_menu_start_el', 'bitbar_generate_nav_dropdown', 10, 4 );
    function bitbar_generate_nav_dropdown( $item_output, $item, $depth, $args ) 
    {
    	// If we're working with the primary or secondary theme locations
    	if ( 'site-area-1' == $args->theme_location || 'site-area-2' == $args->theme_location ) {
    		// If a dropdown menu is detected
    		$dropdown = ( in_array( 'menu-item-has-children', $item->classes ) || in_array( 'page_item_has_children', $item->classes ) ) ? true : false;
    		if ( $dropdown ) :
    			// Add our arrow icon
    			$item_output = str_replace( $args->link_after . '</a>', $args->link_after . '<span role="button" class="dropdown-menu-toggle" aria-expanded="false"></span></a>', $item_output );
    		endif;
    	}
    	
    	// Return the output
    	return $item_output;
    }
    // end down arrow segment
    
    // Following adds search icon and field to menues declared in the second if statement.
    
    add_filter( 'wp_nav_menu_items','generate_menu_search_icon', 10, 2 );
    function generate_menu_search_icon( $nav, $args ) 
    {
    	$generate_settings = wp_parse_args( 
    		get_option( 'generate_settings', array() ), 
    		generate_get_defaults() 
    	);
    	
    	// If the search icon isn't enabled, return the regular nav
    	if ( 'enable' !== $generate_settings['nav_search'] )
    		return $nav;
    	
    	// If our primary menu is set, add the search icon
        if( $args->theme_location == 'primary' || $args->theme_location == 'site-area-1' || $args->theme_location == 'site-area-2' )
            return $nav . '<li class="search-item" title="' . _x( 'Search', 'submit button', 'generatepress' ) . '"><a href="#"><i class="fa fa-fw fa-search"></i></a></li>';
    	
    	// Our primary menu isn't set, return the regular nav
    	// In this case, the search icon is added to the generate_menu_fallback() function in navigation.php
        return $nav;
    }
    
    /* This function is used to prevent secondary menu's collapse on mobile devices. 
     Note: to make it work fully there is a css declaration to 
     .secondary-navigation .menu-toggle {display: none;} 
     */
    
    add_action( 'after_setup_theme', 'theme_slug_setup' );
    add_action( 'wp_enqueue_scripts', 'generate_dequeue_secondary_nav_mobile', 999 );
    function generate_dequeue_secondary_nav_mobile() {
       wp_dequeue_style( 'generate-secondary-nav-mobile' );
    }
    /* end */

    Any feedback and bug fixes /tune up is welcome.
    Once again the entire system falls apart if page parents are not used.

    I think that about wraps up this issue. But fret not, there are still a dozen more things about this site I need to do so you might hear from me yet. Thanks again for the help Tom.

    #200831
    Tom
    Lead Developer
    Lead Developer

    Thanks for sharing your code, I’m sure someone will find it useful 🙂

Viewing 8 posts - 1 through 8 (of 8 total)
  • You must be logged in to reply to this topic.