Show menu based on WordPress login status

In this example, I will show you how to display a different menu for users based on their login status for the WordPress TwentyTen theme.  This process can be adapted to any theme (and using the same principles, could be adapted to use anywhere on your WP site).

Some Prerequisites

This is primarily for those using WP-Members™ who have asked about showing different menu items based on a user’s login status; but the method described is not limited to use with the plug-in.  This will work with any WordPress installation.

This post assumes that the reader is already familiar with creating menus through the WordPress admin panel.  If not, you can familiarize yourself with this process via the WordPress Codex.

It is VERY important to note that you should not make the discussed edits to TwentyTen directly.  You should be using a child theme for any changes, otherwise, when you upgrade WordPress or TwentyTen, your changes will be overwritten.  A tutorial on creating child themes is not the purpose of this post.  If you are not familiar with this process, begin with the WordPress Codex description of Child Themes.

The Process

First, create two menus.  This is done in your WP admin panel under Appearance > Menus.  For this example, I created on called “logged-in” and one called “logged-out”.  It should be intuitive which is which.

For the “logged-in” menu, add the pages and content you want in the menu for users who are logged in.  For the “logged-out” menu, put in the content to display if the user is not logged in.

To implement these menus, you will make a slight change to the header.php file for the TwentyTen theme.  Look for the following line in this file:

<?php wp_nav_menu( array( 'container_class' => 'menu-header', 'theme_location' => 'primary' ) ); ?>

Replace that line with the following:

<?php
if( is_user_logged_in() ) {
	$menu = 'logged-in';
} else {
	$menu = 'logged-out';
}

wp_nav_menu( array( 'menu' => $menu, 'container_class' => 'menu-header', 'theme_location' => 'primary' ) );
?>

Basically, we are just adding another parameter for wp_nav_menu to determine which menu to load.  We are using a variable $menu that will provide the menu name depending on the user’s login status.

It’s that simple.

For a related discussion on how to display different elements in the Loop area of your theme, see this post: Blocking Content in a Custom Template.

  • Franc

    Hello,

    I have a small problem that I can’t figure out how to fix. At the end of each post there’s the Leave a reply option that says you must be logged in to leave a reply. Which is ok since only registered users are allowed to post comments.
    The problem is that the link leads to a WordPress lookin login form and not the one I created in WP Members. I tried various settings in the WP dashboard but I can’t convience the redirect to go to the login/register form.
    So how can I change this redirect part or just insert a plain link to the form? Thank you so much for your help.

    • http://butlerblog.com Chad

      Franc – the link you are talking about is put in at the theme level. There are two ways to change this. One is to add some arguments to the comments_form function in your theme’s comments.php file.

      The other would be to create a filter for login_url like:

      function my_login_url( $login_url ) 
      {
          return 'http://yourdomain.com/your-login-page';
      }
      add_filter( 'login_url', 'my_login_url', 1 );
      

      The nice thing about that method is that it redirects everyone away from the backend login to the login url you specify (not just for comments). The downside is that “everyone” includes you – so you would need to change some habits in logging in and accessing the dashboard.

      • Fanc

        Chad thank you very much for your reply. I would like to create a filter login like you suggested. If you would be so kind, could you please tell me exactly where to insert that because I really really don’t want to mess anything up…
        Thanks

        • http://butlerblog.com Chad

          Something like that goes into your theme’s functions.php file. You can just tack it on to the end of the file – just note that if there is a closing php delimiter ( ?> ), that you are pasting *inside* of it.

    • Vladimir

      Hi, is it possible to adapt it to the Simploblack theme?, It would be great!… thanks

      • http://butlerblog.com Chad
        • Vladimir

          Thank you so much for your help, Chad.

          One more question, I’m trying to show the registration form, which should include only the fields I selected on the Setting’s Field section.

          I don’t know what URL to use in the ‘Register Page URL’ field in order to show the Register link.

          thanks again ;o)

          • http://butlerblog.com Chad

            That’s only if you set up a specific register page and you want to have the link to it show at the bottom of the login form. If you set up a specific registration page with the shortcode [wp-members page="register"], you would put the URL of that page in there.

          • Vladimir

            Thank you, thank you very much Chad. You rock!!

  • Miguel Alas

    Hi Chad! Great plugin!
    I’ve installed the plugin and was looking for a way to redirect the user to any page I choose after login. I mean I have a main page 1 and main page 2. The main page 1 is for not logged user and as soon they login may be redirected to main page 2. How can I make this?

    Thanks in advanced!!

    • http://butlerblog.com Chad

      You could set up one page and separate the content based on login status using shortcodes. The ‘status’ shortcode will display different content based on user login status:

      [wp-members status="out"]This is content that will display to users who are NOT logged in.[/wp-members]

      [wp-members status="in"]This is content that will display to users who ARE logged in.[/wp-members]

      The caveat is that you do not get the benefit of inline login and registration (although if you have the login widget on the sidebar, that will still be active).

  • http://www.wilycode.com Robert

    Hi Chad,
    I’ve followed the instructions in this post but I have a different template (not twenty ten or eleven) in which a custom menu is already used for the register/login links that is put into the header area on the widgets screen of WP admin area. Before my header.php had this code( are replaced by [ and ] in the hopes that you’ll get to see the code):
    [nav class="primary"]
    [?php wp_nav_menu( array(
    'container' =] ‘ul’,
    ‘menu_class’ =] ‘sf-menu’,
    ‘menu_id’ =] ‘topnav’,
    ‘depth’ =] 0,
    ‘theme_location’ =] ‘header_menu’
    ));
    ?]
    [/nav][!--.primary--]

    I added the menu parameter like you said, but it seems that in this theme the header widget is showing the custom menu, which appears above the regular header menu:
    [div id="header-widget"]
    [?php if ( ! dynamic_sidebar( 'Header' ) ) : ?]
    [!-- Widgetized Header --]
    [?php endif ?]
    [/div]

    So I’m still seeing my static custom header (in the header-widget div) and not the logged-in or logged-out ones. Do you know how I can change which widget is shown based on logged in status?
    Thanks,
    Robert

    • http://butlerblog.com Chad

      It all boils down to using is_user_logged_in. You might have two completely different headers for logged in/logged out users.

      if( is_user_logged_in() ) {
      	// the user is logged in.
      	// any code for the logged
      	// in user goes in here.
      } else {
      	// the user is not logged in.
      	// anything you show to 
      	// logged out users goes here.
      }

      Also, if you are strictly limiting an element to just logged in users and there is nothing in there that needs to render for the logged out state, you can just drop the else{ … } part of it.

  • Jonathan

    Thanks for this really effective tip. I customized it slightly to work with my client’s BuddyPress site and it works perfectly!

  • steve grace

    I got this to work but is there a way to make the code check for role the user is? I mean can I have a menu for Subscriber / Contributor / Author? I want each role to have access to different parts of the site.

    • http://butlerblog.com Chad

      Since WordPress transitioned from a User Level based system to Roles based system, it is best to query the user capability by using something like current_user_can() and use a capability appropriate to a given role in your situation (as roles and capabilities may vary from install to install).

  • http://www.wilycode.com Robert

    Hi Chad,
    I like the ease of use of this plugin but I want to know if you’ve replaced any of the following functions in your plugin. I’ve been trying to auto-login after creating a new account, but it seems that the cookies are not being set correctly. I’m using this code:

    wp_set_current_user($user_id, $username);
    wp_set_auth_cookie($user_id,true);
    do_action(‘wp_signon’, $username);

    If I check is_user_logged_in() it returns true, but when I redirect to the index page or open a new tab my new user is not logged in. Is there a different way for me to auto-login users with your WP-Members plugin installed?
    Thanks,
    Robert

  • Donte

    Hi Chad Im Very New to wordpress,i have wp members installed and working great,Now what I would like to do is fix it so i will have separate pages for logged in users and not logged in users.If any code is involved please tell me to insert it..Thanks in advance..

    • http://butlerblog.com Chad

      I would suggest reviewing the Quick Start Guide and the Users Guide, both of which can be found at http://butlerblog.com/wp-members

  • ar

    Hi, how to have a different container_id’s wp_nav_menus value per user state, please? I am using:
    if( is_user_logged_in() ) {
    $menu = ‘logged-in’;
    } else {
    $menu = ‘logged-out’;
    }

    wp_nav_menu( array(
    ‘menu’ => $menu,
    ‘container_class’ => ”,
    ‘container_id’ => ‘id-for-logged-in-user’,
    ‘theme_location’ => ‘primary’
    )
    );

    using the above code I will print that ‘id-for-logged-in-user’ always in the HTML markup.
    I would to have that id value only when user is logged in.
    Thanks for any help.

    • http://butlerblog.com Chad

      Just add another variable for your container id.

      • ar

        Thanks for the quick answer: but how to do that? i am not sure that i gotcha

  • ar

    Like:

    $menu,
    ‘container_id’ => $containerID
    )
    );
    ?>

    thanks

    • http://butlerblog.com Chad
      if( is_user_logged_in() ) {
      $menu = ‘logged-in’;
      $container = 'id-for-logged-in-user';
      } else {
      $menu = ‘logged-out’;
      $container = 'some-other-container';
      }
  • http://compurocketusa.com/ Tino

    Hi,

    Do you know if it is possible to insert the login window and functionality in a different site?

    I have a landing page and want to have the username and password windows available at this page and then, when you input that info, go directly to the WP site.

    Thanks!

    • http://butlerblog.com Chad

      It would be possible to build something, yes. You would need access to the WP database for validating login credentials. You could use WP and/or WP-Members functions, or write your own.

  • Ben

    Hi Chad,

    I can’t seem to get this to work… I’m working with a child theme of Twenty Eleven and am replacing the following code (which is a little different I noticed, however, I’m unfamiliar with PHP):

    ‘primary’ ) ); ?>

    I then changed the menu names to match my own and gave it a try. All it is doing is showing the same menu (whether you’re logged in OR out), only the styling is changing.

    Any ideas?

    Thanks in advance,

    Ben

    • http://butlerblog.com Chad

      Not sure what you have there – you can’t really post code in the comments so whatever you put in there I can’t read. You could send it via the contact form and I’ll see if I can take a look at it.

  • Ron

    Hi Chad,

    I’m hoping you can help. I really like your plugin but I need added functionality. I would like to charge for access to certain pages (not posts), using paypal. Is there any plugin that works with yours that would have the following settings for registration: non-registered, registered (gives access to replying to posts/polls etc) and payed registered (gives access to certain pages that otherwise they would not have access to). Your plugin allows for the first two options but I’m also looking at adding to the functionality with the third option.

    Thanks for any input you’ll be able to give,

    Ron

    • http://butlerblog.com Chad

      I do have a PayPal add-on in development. It’s about a month away from release.

      • Ron

        Looking forward to it. If it includes a trial period option, that would be perfect. Thanks for the great work!

  • Pingback: Creating menus based on login status

  • RDC4

    Hey, I would like to do it but at the top menu, and I’m using a different theme, here’s the code of my header.php:

    ‘menu_order’, ‘container_class’ => ‘ts-menu-top’, ‘menu_class’ => ‘sf-menu’, ‘fallback_cb’ => ‘ts_top’, ‘theme_location’ => ‘top’ ) );
    else : ?>

    Can anybody help me please?

    • http://butlerblog.com Chad

      I would highly recommend reading the codex entry on using wp_nav_menu. What you need to do is add a parameter to the array of arguments for the menu name. This would be the parameter ‘menu’ which you are going to define as a variable. So you are adding the parameter 'menu' => $menu. If you read this post and the codex entry, everything you need is there so extrapolate this example to any theme.

      • http://adic-org.com Jean-Baptiste Bouquet

        Hello Chad, I’d like to second the above request to display menus/content based on a custom added field (i.e. Dentist, Dental Hygienist, Dental Assistant in my case). I have limited knowledge in PHP and would be willing to pay for some integration help.

        And I wanted to share with you: I use a WP-Members login page but I used the Theme-My-Login plugin to change the “Login” link that points to it to display “Log Out” when logged in (by referencing the Login page ID). Maybe you could include that feature in your next update? It’s very useful and I could deactivate the TML plugin Cheers

        • http://butlerblog.com Chad

          Thanks for the questions/comments. I would probably be inclined to include a tutorial on setting up something like that on rocketgeek.com. I in the process of moving all support to a premium based model and am doing it on that site.

          On your question/comment about the TML login link, I’m not really sure I follow exactly what you are saying. Could you clarify?

          • http://adic-org.com Jean-Baptiste Bouquet

            For clarification, if you take a look at adic-org.com, the login link is marked LOG IN when navigating anonymously and it switches to LOG OUT once you’re logged in. This is done through some code from TML, not WP-Members. I just don’t know which part ;) So it’d be nice to have the same thing in WP-Members :)

  • Genesis

    Hi Chad, is it possible to use wp-members added fields to act as a filter to show a different menu? Thanks.

    • Genesis

      Appreciate the posting but I’ve got it Chad!
      GREAT PLUGIN!
      +1 like

    • http://adic-org.com Jean-Baptiste Bouquet

      Hello Chad, I’d like to second the above request to display menus/content based on a custom added field (i.e. Dentist, Dental Hygienist, Dental Assistant in my case). I have limited knowledge in PHP and would be willing to pay for some integration help.

      And I wanted to share with you: I use a WP-Members login page but I used the Theme-My-Login plugin to change the “Login” link that points to it to display “Log Out” when logged in (by referencing the Login page ID). Maybe you could include that feature in your next update? It’s very useful and I could deactivate the TML plugin ;) Cheers

  • Sara

    Thank you so much for this code! You’re awesome!!! :D

  • http://www.isharetrip.com.au prasann

    Hey , g8 tips
    thanks ,
    I wan to create menu as per user login means if business user login than they can see different menu, If admin login than they can see different menu and if reader login than they can see different menu.. Any help guys ?

    • http://butlerblog.com Chad

      That would be the same concept as presented here, but you would need to alter the conditional test (the if() statement) to be testing for the user’s role/capabilities.

  • Sander

    Many thanks for this info on this site

    I am trying as well something out and need a bit of help

    I am playing with the next code
    I dont want to use it for login but like follow
    if user comes from this link show menu Topsummer
    http:www.test.com/?profile=Summer – show menu Topsummer
    http:www.test.com/?profile=Winter – show menu Topwinter

    What do i need to change, willing to pay as well for it!

    if( is_user_logged_in() ) {
    $menu = ‘Topsummer’;
    } else {
    $menu = ‘Topwinter’;
    }

    wp_nav_menu( array( ‘menu’ => $menu, ‘container_class’ => ‘menu-header’, ‘theme_location’ => ‘primary’ ) );

    Thanks Sander

    • Sander

      this is working can someone tell me its 100procent oke
      Its working but maybe because i am beginner i did something wrong

      $uri = $_SERVER['REQUEST_URI'];
      if ( strpos($uri,’/?profile=Summer’) !== false ) {
      $menu = ‘Topsummer’;
      } else {
      $menu = ‘Topwinter’;
      }

      wp_nav_menu( array( ‘menu’ => $menu, ‘container_class’ => ‘menu-header’, ‘theme_location’ => ‘primary’ ) );

      • http://butlerblog.com Chad

        You’d be better off just grabbing the passed querystring directly:

        $profile = $_GET['profile'];
        if( $profile = 'Summer' ) {
        $menu = 'Topsummer';

        etc…

  • Raghav

    Chad,

    I’ve a wordpress membership site. How to have different header.php based on different logins.
    Eg: Users are: Print, Web and Free

    When Free user logs in – I want header1.php to load
    When Print user logs in – I want header2.php to load
    When Web user logs in – I want header3.php to load

    If nobody has logged in the default header.php stays

    Please assist on how to do this.

    Regards,
    Raghav.

    • http://butlerblog.com Chad

      That’s way more complicated that you need to make it. Loading different header files would mean that any template file that calls the header would need to have a conditional statement to determine which header to load. It would be easier to have one header.php file, then execute one conditional based on that.

      I don’t know what you are using to determine what the user status is, but essentially, you would execute a php switch on whatever the criteria is:

      switch ($your_criteria) {
      case “free”:
      // do something here for header1
      break;
      case “print”:
      // do something else
      break;
      case “web”:
      // do something else
      break;
      default:
      // do the default state
      break;
      }

  • http://www.permaculturesydneywest.com.au Robert

    Hi I need some help,

    I do not know if there is plugin or if there is some code out there for this already. I am fairly new to wordpress.

    I need a plugin or code for the following scenario:

    There are 2 types of users who can log in to my website.

    Once a user logs in to my website they should see specific menu tabs for the user type.

    One type of user (Committee) can see and has access to all the menu tabs.

    The second type of user (Member) can see and has access to all menu tabs just not the Committee Member menu tab. (Committee tab must be hidden from them).

    Your help would be appreciated.

    Cheers
    Robert

  • Sherle

    Is it possible to make this work with a Superfish menu?

  • Sherle

    Is it possible to make this work with a Superfish menu? Wrong email in last post.

  • Hasse

    Hi Chad,
    I´m a newbie user of WP with the theme Avada. I would like to create a menu for users that are logged in as ‘authors’ and a diffeent menu for not logged in users (should not see the members tab in the menu).
    I have installed WP-members and can´t solve this problem. Please help me!

    I can´t use the code that´s designed for TwentyTen.

    • http://butlerblog.com Chad

      The code example is just that – and “example.” It’s not necessarily intended to be cut and paste. I do write code snippets for specific applications for support members at rocketgeek.com.

      For what you want to do, you need two conditions – first the user needs to be logged in (otherwise, you don’t know their role). Use is_user_logged_in for that. Second, if they are logged in, you can use current_user_can to determine if they are an author (or higher) or not.

      http://codex.wordpress.org/Function_Reference/is_user_logged_in
      http://codex.wordpress.org/Function_Reference/current_user_can

  • przemek

    Hi Chad, many thanks – everything work well :)