0

I'm using the below code to display two different menus in my storefront based child theme based on a users logged in status. But When I have a secondary menu (links by the search bar) it is replaced with the primary menu. Is there a way to differentiate between the two when checking for logged in users?

The below code is in my functions.php file.

//Custom Nav Menu
function custom_wp_nav_menu_args( $args = '' ) {
    if( is_user_logged_in() ) {
        $args['menu'] = 'logged-in';
    }else { 
        $args['menu'] = 'logged-out';
    } 
    return $args;
}
add_filter( 'wp_nav_menu_args', 'custom_wp_nav_menu_args' );

The theme is the default storefront theme, which should displays the secondary menu to the left of the search box. As you can see here its displaying (either) the logged-in or logged-out menu.

Please see Selected answer for more information. My Working Code...

//Custom Nav Menu
function custom_wp_nav_menu_args($args) {
    if ( isset($args['theme_location']) && 'primary' === $args['theme_location'] ) {
            // do something
        if( is_user_logged_in() ) {
            $args['menu'] = 'logged-in';
        }else { 
            $args['menu'] = 'logged-out';
        }
    } 
    return $args;
}
add_filter( 'wp_nav_menu_args', 'custom_wp_nav_menu_args' );
  • 2
    Could you add pictures to better understand your issue? – Himad Jun 4 at 0:33
  • @himad I went ahead and added a screenshot. Please see above. – T. Thomas Jun 5 at 5:35
1
+50

wp_nav_menu_args is a filter inside wp_nav_menu, which is used to display navigation menus on your site. The $args parameter passed to the filter is an array containing the wp_nav_menu arguments. By default they are the following,

$defaults = array(
  'menu'            => '',
  'container'       => 'div',
  'container_class' => '',
  'container_id'    => '',
  'menu_class'      => 'menu',
  'menu_id'         => '',
  'echo'            => true,
  'fallback_cb'     => 'wp_page_menu',
  'before'          => '',
  'after'           => '',
  'link_before'     => '',
  'link_after'      => '',
  'items_wrap'      => '<ul id="%1$s" class="%2$s">%3$s</ul>',
  'item_spacing'    => 'preserve',
  'depth'           => 0,
  'walker'          => '',
  'theme_location'  => '',
);

You can find these also in the wp_nav_menu code reference and in its source code. (These are merged with the theme supplied arguments by wp_parse_args before being passed to the wp_nav_menu_args filter.)

This means you can use the parameter to check for example which location the filter is currently handling.

add_filter('wp_nav_menu_args', 'my_wp_nav_menu_args_filter');
function my_wp_nav_menu_args_filter($args) {
  if ( isset($args['theme_location']) && 'my-theme-location' === $args['theme_location'] ) {
    // do something
  }
  return $args;
}

(For Storefront the location slug is secondary, which you can find in the source code.)

| improve this answer | |
  • @t-thomas -- The answer by @antti-koskinen is great, but it is implying your answer: you should be using the hook to check for the exact spot in which you desire to change the output (in this case, to the left of the search bar) in addition to performing your own is_user_logged_in() check. Otherwise, you'll be modifying every spot where a menu appears on your site. (The "do something" in @antti-koskinen 's code is where you would change the menu being displayed.) – Mort 1305 Jun 6 at 17:00
  • Thank you @mort1305 for the clarification. Now as I read my answer again I realize it rather poorly worded and only implying the solution as you note. – Antti Koskinen Jun 6 at 18:55
  • It's an awesome answer, $antti-koskinen ! – Mort 1305 Jun 7 at 1:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.