Have you ever wished you could have your navigation menu change depending on whether a user is logged in or not?  For a logged in user they would see a logout option and maybe a link to their profile.  Whereas those not logged in would be offered a login menu link.  Sounds simple enough.

For the site in question, I am using a plugin to allow users a front end method of logging in and editing their profile without sending them to the WordPress admin area.  It gives the user a better visual experience to be sure, and keeps them out of the admin area, which could get messy.  I really like the plugin, it’s simple and adds very little overhead, but there’s no way of allowing for changing menus for logged in users or guests.  I was sure there had to be a way to do this so I went looking.

Right now you might be thinking “just use the built in meta menu”.  Yes, you can do that.  But I never really liked it, do you?  Oh sure there are plugins to modify it which of course adds another plugin to your site.  This is actually what I do on this site but that may be changing real soon.  There are several plugins that can help you with displaying different menus depending on who is logged in or not, and if you’re using one of the many membership plugins you probably already have this function built-in with that.  But what if your plugin doesn’t have this option?  Or what if you simply would like to allow this without using yet another resource heavy plugin?

Plug In or Out?
Don’t get me wrong I like plugins just fine.  But often they add extra code and delays and database entries and hits that simply make a WordPress site take a very long time to load.  Many themes do this as well, especially those that rely on resource hogging frameworks.  Use a child theme and it only adds to the problem.  For these reasons I prefer to develop themes from the ground up and utilize the plethora of functions already available in WordPress and PHP before turning to plugins or commercial themes or frameworks.

In the course of coding WordPress themes or plugins I often turn to the web to find answers.  There’s no shortage of blogs and forums out there addressing all things WordPress and most of the time I can find what I’m looking for fairly quickly.  But I am beginning to see most “solutions” to a problem rely more and more on plugins.  That’s great for those who do not want to get into coding everything.  But what if you understand code and want to do something without the added hit of yet another plugin?

Conditional Menus
There are many reasons to want conditional menus other than the scenario I had.  You could provide anyone with direct access to where they need to be based on their user access level.  That is somewhat the function of the admin bar at the top when you’re logged in, but this can be more granular.  And maybe you don’t want your authors poking around in the admin area, so you disable the admin bar and give them links in a menu.

The approach I took is fairly simple and utilizes all the functions your theme and WordPress are using without any added overhead besides calling a WordPress function one additional time.  In my search I found a few different approaches that required hooks or filters and added functions in your functions.php file, none of which I could get to work very well.  This solution actually dawned on me while reviewing one of those hook functions.  The only caveat is you’ll need to edit a sidebar file directly.  If you’re using your own custom theme this is no problem.  If you aren’t you may want to carefully consider doing this, as the next time your theme updates your menus will break.

In directly editing the theme sidebar file where you want your menu to appear, you’re taking advantage of the fact that your sidebar is already being registered so there will be no extra load on your site.  We will be calling the built in menu function and telling it to load a specific menu based on the user login credentials.  This adds no new functions or hooks and simply by utilizes what WordPress is already doing and already “knows” about the user to make the “decision” between menus.

Your theme most likely is registering your sidebar files, and should also be registering menus as well, all in your functions.php file.  We will be adding to the menu registration function, but that’s it.  In my case here’s how I modified the menu registration in my theme functions.php file.

// BEFORE
function register_menus() {
  register_nav_menus(
    array(
      'main-menu' => __( 'Main Menu' )
    )
  );
}
add_action( 'init', 'register_menus' );

// AFTER
function register_menus() {
  register_nav_menus(
    array(
      'main-menu' => __( 'Main Menu' ),
      'user-menu' => __( 'User Menu' ),
      'guest-menu' => __( 'Guest Menu' )
    )
  );
}
add_action( 'init', 'register_menus' );

As you can see I added two new menus to my theme, ‘User Menu’ and ‘Guest Menu’.  That’s it, we’re done with the functions.php file.

Next, head over to Dashboard > Appearance > Menus.

You probably already have a “main” menu for your site and it should be assigned to your main menu area.  In this example you need to add two additional menus, one named ‘guest-menu’ and the other named ‘user-menu’.  The guest-menu has only a login link and should be assigned to the Guest Menu theme location.  The user-menu has a logout and profile link and should be assigned to the User Menu theme location.

We are done with menus.

Now open the sidebar file where your main menu is called.  IF you are placing your menu as a widget, once we’re done with this you’ll want to disable or remove that widget.  For now, if you are already calling the main menu in your sidebar file it should look something like this:

<div id="sidebar-left">
<ul>
<?php wp_nav_menu( array( 'theme_location' => 'main-menu' ) ); ?>
<?php if ( function_exists ( dynamic_sidebar('left') ) ) : ?>
<?php dynamic_sidebar ('left'); ?>
<?php endif; ?>
</ul>
</div>

If you aren’t placing your main menu with a function call in the sidebar, but rather as a widget, you’ll want to add the

<?php wp_nav_menu( array( 'theme_location' => 'main-menu' ) ); ?>

function call to your sidebar file.  Just make certain it’s BEFORE the dynamic_sidebar() function call or your menu will not display, this is important.

Now let’s add the conditional part.  We’re going to tell WordPress in these next few lines if the user is logged in to load the user menu, and if not load the guest menu.  You can place this decision making routine before or after your main menu which ever you prefer.  I placed mine after the main menu.  So the final code for the sidebar will look like this:

<div id="sidebar-left">
<ul>
<?php
wp_nav_menu( array( 'theme_location' => 'main-menu' ) );
if( is_user_logged_in() ) {
    wp_nav_menu( array( 'theme_location' => 'user-menu' ) );
} else { 
    wp_nav_menu( array( 'theme_location' => 'guest-menu' ) );
}
?>
<?php if ( function_exists ( dynamic_sidebar('left') ) ) : ?>
<?php dynamic_sidebar ('left'); ?>
<?php endif; ?>
</ul>
</div>

That’s it.  Place your edited functions and sidebar files on your server in your theme’s folder and you should see your new conditional menus.

This can also be applied to showing logged in users any number of things in a sidebar in which case you would only be editing the sidebar file and nothing more.  It’s a solution that works well IF you build your own theme and it keeps the overhead cost of your site lower.

Follow comments on this post with this RSS 2.0 feed.
Leave a comment, or trackback from your own site.

You must be logged in to post a comment.

. . :   design & hosting by creed3.com   : . .