In a project that am working on, the requirement is to display different WordPress menus on different pages (views) in the Secondary Nav.
Ex.: 'Shop Menu' on a specific Shop page, 'Events Menu' when on any page generated by Modern Tribe's The Events Calendar, 'Blog Menu' in all other views etc.
Screenshots:
Front page:
Shop (a static Page):
Product 1 (sub page of Shop):
Posts page and all other views (this is like the default):
This tutorial can also be applied to conditionally show different menus in Primary Navigation Menu.
Using Genesis Simple Menus plugin is not an option because it only lets me assign menus per Post, Page, Category or Tag, but not for other views.
Using Bill Erickson's Genesis Subpages as Secondary Menu plugin is not an option because the site's navigation system isn't based on just Pages and sub Pages.
I looked at one of my earlier Posts on this topic titled How to conditionally replace Navigation menu in Genesis and figured it could be simplified and hence this tutorial.
First we are going to use a function from the codex which returns true when we are on a Page in question (by its ID) or any of its sub Pages.
Add the following in child theme's functions.php:
// Returns true when we are on a Page in question or any of its sub Pages | |
// https://codex.wordpress.org/Function_Reference/is_page#Testing_for_sub-Pages | |
function is_tree( $pid ) { // $pid = The ID of the page we're looking for pages underneath | |
global $post; // load details about this page | |
if ( is_page( $pid ) ) | |
return true; // we're at the page or at a sub page | |
$anc = get_post_ancestors( $post->ID ); | |
foreach ( $anc as $ancestor ) { | |
if( is_page() && $ancestor == $pid ) { | |
return true; | |
} | |
} | |
return false; // we aren't at the page, and the page is not an ancestor | |
} |
Now is_tree( '7' ), for example, returns true if the current page is 'Shop' (this has the ID of 7) or any of its sub Pages: 'Product 1' and 'Product 2'.
Next go ahead and create several menus for the different views. Ex.:
At Appearance > Menus > Manage Locations, assign your main or default menu to Secondary Navigation Menu location.
Finally we use wp_nav_menu_args filter to assign menus conditionally in Secondary Navigation Menu location like so:
To view the full content, please sign up for the membership.
Already a member? Log in below or here.
Awesome tutorial ! That header also looks great. Do you have a tutorial on how to create the header so that the logo, navigation and social icons are all in-line ?
Thank you !
Here you go: http://sridharkatakam.com/genesis-header-with-logo-nav-and-social-icons-in-line/
Wow, that was quick. Thank you Sridhar ! Amazing support.
Hey Sri, how would you achieve this for all archives / posts / blog home?
I want to show categories as a secondary nav within the blog archives and posts, but not the home or static pages.
Ignore – Found it:
// Remove secondary nav except for posts and archives
add_action(‘template_redirect’, ‘remove_category_menu_exclude_archives_posts’);
function remove_category_menu_exclude_archives_posts() {
if ( !is_archive() && !is_single() && !is_page(‘blog’) )
remove_action(‘genesis_after_header’, ‘genesis_do_subnav’);
}
It’s not recommended to use Blog Page Template (if you aren’t using one, please ignore).
Hi Sridhar,
Thanks so much for this tutorial (and the many others that have helped me so far!).
I’m wondering if there a way to set this up, so the sub-menu items for each parent are visible on hover AND remain visible when I click on them? I’m looking at something like this: http://codecanyon.net/item/animated-horizontal-dropdown-menu/3584222
If you have any tutorials you could guide me towards that would be super!
Thanks so much!
Lisa
Hi Lisa,
Can be done with UberMenu.
https://sridharkatakam.com/go/ubermenu/
Sridhar, you have no idea how many hours I’ve spent trying to figure this out. Ridiculous, really, given how simple the solution was 🙂 This is a great plugin! Thank you so much for coming to the rescue!
Hi Sridhar: I’m getting a syntax error when I use the second section of code in my functions file. I think I’m copying it as you have it and am just changing the page ids and menu titles. Can you see what I’m doing wrong?
Thanks,
Julia
// Assign menus conditionally in Secondary Navigation Menu location
add_filter( ‘wp_nav_menu_args’, ‘replace_menu_in_secondary’ );
function replace_menu_in_secondary( $args ) {
if ( $args[‘theme_location’] != ‘secondary’ ) {
return $args;
}
if( is_tree( ’300’ ) ) { // About Page or any of its sub pages
$args[‘menu’] = ‘About’;
} elseif ( is_tree( ‘226’ ) ) { // JUMP Page or any of its sub pages
$args[‘menu’] = ‘JUMP’;
} elseif ( is_tree( ‘10’ ) ) { // Events Page or any of its sub pages
$args[‘menu’] = ‘Events’;
} elseif ( is_tree( ’12’ ) ) { // Studio Page or any of its sub pages
$args[‘menu’] = ‘Studio’;
}
return $args;
}
Works perfect but does anybody know how not to show sub menu on the homepage?
Just incase anybody else has the same problem
Probably not the bestway, but it worked. I created a menu called blank and added nothing to it and then added the following to the rest of the arguments
elseif ( is_front_page() && is_home() ) { // About Page or any of its sub pages
$args[‘menu’] = ‘blank’;
Hi, Sri. I am trying to put 3 different menus on 3 different category pages – thought I could add the code below – but it is not working for me – can you tell me waht I am doing wrong please
http://dev2.addapinch.com/cooking
http://dev2.addapinch.com/traveling
http://dev2.addapinch.com/living
[code]
// Returns true when we are on a category in question or any of its sub categorys
// https://codex.wordpress.org/Function_Reference/is_category#Testing_for_sub-categorys
function is_tree( $category ) { // $category = The ID of the category we’re looking for categorys underneath
global $post; // load details about this category
if ( is_category( $category ) )
return true; // we’re at the category or at a sub category
$anc = get_post_ancestors( $post->ID );
foreach ( $anc as $ancestor ) {
if( is_category() && $ancestor == $category ) {
return true;
}
}
return false; // we aren’t at the category, and the category is not an ancestor
}
// Assign menus conditionally in Secondary Navigation Menu location
add_filter( ‘wp_nav_menu_args’, ‘replace_menu_in_secondary’ );
function replace_menu_in_secondary( $args ) {
if ( $args[‘theme_location’] != ‘secondary’ ) {
return $args;
}
if( is_tree( ‘4’ ) ) { // Shop category or any of its sub categorys
$args[‘menu’] = ‘Category’;
} elseif ( is_tree( ‘6’ ) ) { // Video category or any of its sub categorys
$args[‘menu’] = ‘Living’;
} elseif ( is_tree( ‘3’ ) ) { // Video category or any of its sub categorys
$args[‘menu’] = ‘Traveling’;
return $args;
}
[/code]
I did correct my code at the bottom.
// Assign menus conditionally in Secondary Navigation Menu location
add_filter( ‘wp_nav_menu_args’, ‘replace_menu_in_secondary’ );
function replace_menu_in_secondary( $args ) {
if ( $args[‘theme_location’] != ‘secondary’ ) {
return $args;
}
if( is_tree( ‘4’ ) ) { // Cooking category or any of its sub categorys
$args[‘menu’] = Cooking;
} elseif ( is_tree( ‘6’ ) ) { // Living category or any of its sub categorys
$args[‘menu’] = ‘Living’;
} elseif ( is_tree( ‘3’ ) ) { // Traveling category or any of its sub categorys
$args[‘menu’] = ‘Traveling’;
}
return $args;
}
I know I could use the Genesis Simple Menus – but I would like for it to show on the posts and the sub categories of the parent category
GREAT! Also works with primary nav if you change ‘secondary’.