Guest only menu items

I have posted before about a menu CSS snippet I found to only show menu items to logged in users. I have been looking for a suitably elegant way to reverse this and have a menu item ONLY visible to users who are NOT logged in.

Today I have arrived at a solution. This is not the only solution, and by all means, it’s not the best. But for my needs, this is perfect (see notes in the Conclusion).

This needs to be done in three parts and this will give you the option to have menu item(s) displayed for ONLY logged in users, as well as having them displayed for ONLY guests. The choice is yours and can be changed at anytime easily in the dashboard of wordpress single blog sites, or blogs a part of the multi-site setup–although some of the setup process might not be available to you in a multi-site setup if you are not the super-admin.

Step 1 — adding code to functions.php

Insert the following code into your functions.php file:

add_filter('body_class','not_logged_in_class');

function not_logged_in_class($classes = '')
{
	if ( !is_user_logged_in() ) {
		$classes[] = 'not-logged-in';
	}

	return $classes;
}

Step 2 — adding style to your theme’s CSS

Add the following CSS to your style sheet:

#menu-mainmenu li.logged-in-nav {
display: none;
} 

body.logged-in #menu-mainmenu li.logged-in-nav {
display: list-item;
}

body.not-logged-in #menu-mainmenu li.logged-out-nav {
display: list-item;
}

#menu-mainmenu li.logged-out-nav {
display: none;
}

IMPORTANT: The menu I use for my primary menu is called “MainMenu” ergo my CSS markup above includes “#menu-mainmenu”. Where I originally obtained the inspiration for this source used “#nav”. It may be prudent to first determine what your theme throws out as an ID for the navigation menu. Just check the page source and find out what it is. You want the name of the ID associated with the unordered list that is associated with the list items of where your menu is to be displayed. For example, if you named your primary menu “MyPrimaryMenu”, you should change the above code to “#menu-mymainmenu”. Values I have seen from various blogs include: #nav, #menu, #menu-MENUNAME (without commas of course). DON’T FORGET TO CHANGE THIS.

Step 3 — using the CSS

Create your page, and make sure it appears in your menu. Drag it to the desired location within the menu structure and open the the drop down to the right (downward pointing triangle). On the right under “Title Attribute” there is a text field with the heading “CSS Classes (Optional)”, insert “logged-in-nav” or “logged-out-nav” as appropriate into this box, and save the menu. For something to be visible to only logged-in users, use “logged-in-nav”. For something to only be visible to guests, use “logged-out-nav”.

That’s it! You’re done!

Since the object of this exercise was to have a menu item displayed for only guests, let’s test it out now. View your blog/website and confirm that the menu item is NOT there when you’re logged in. Log out, and check that it DOES appear. If it’s not behaving as expected go back and check your steps. Also, there are some quick things to check listed below in Troubleshooting.

Caveat and conclusion:

Once implemented, this setup gives a simple way to chop and change menu items visibility dependant on whether a user is logged in or not. This has not been tested in an environment where user access management is in place. I have tried various plugins for access management, but none gave me the option to SHOW ONLY to guests.

WARNING: There is one downside to this method. The end-user does not SEE the menu item, because the CSS “hides” it from them. It doesn’t altogether remove it from the page source and screen readers may in fact read the menu item–I have no personal knowledge on this. Anyone viewing the source will see these links — whether logged in or not. So unless you have the destination pages “controlled” in some other way, then maybe this method isn’t the best solution. This suits my purposes, but it might not suit yours.

I hope you find this snippet as useful as I did.

Troubleshooting:

  • Make sure you changed #menu-mainmenu to the appropriate ID name of the unordered list holding the list items for your menu!!! <– this is the most likely cause of it not showing up;
  • Clear the cache for your browser! Should be done first, you don’t want to spend the next hour debugging to find there’s no error! It’s possible the new style wasn’t loaded;
  • Check your spelling! A single simple typing mistake could be to blame, go and double check your work;
  • Make sure you’ve made the appropriate changes in the two files as required and SAVED/UPLOADED to the correct place;
  • If it’s still not there, make sure you’ve edited the correct theme’s files;
  • It could also be the fact your style sheet is not loading, try modifying some other part of the CSS and see if it changes in your browser.

Other notes and advice:

  • You can modify your theme’s style sheet and functions.php file directly–not ideal because subsequent style updates by the theme developer will see your style go out the window;
  • You can create a child theme of your current theme and make the changes there–create the functions.php file and add the code, as well as the styles to the CSS. This is a lot better, and the preferred method when dealing with a fixed theme, but this style and function will be lost when you change the theme;
  • Some theme’s have a CSS injection mechanism which is more ideal, but this also suffers from the lack of carry over to any new and subsequent theme;
  • Finally (and the way I have done it), I found a simple plugin years ago that allows custom CSS to be added and kept across all your themes (for that blog). The plugin allows you to save the CSS in the wp database and is not tied to any theme.

References:


This entry was posted in general and tagged , , , , . Bookmark the permalink.

7 Responses to Guest only menu items

  1. Pingback: Showing menu items to logged in users only | dav3 on wordpress

  2. There are some excellent plugins available to restrict access to pages for guest users. I use Page Restrict, which shows a polite “please log in” message and a login form; so if the guest even does find the links in the source, they’ll be given another roadblock first.

  3. Bug report time…

    Using “Antioch” theme on WordPress 3.1, following these instructions leads to strange results in the footer menu (if created) as well as putting one of the “logged-in-nav” or “logged-out-nav” options in the CSS field of the LAST menu item in the navigation bar, causes the menu to break. It appears as if one of the “<" tags before a "class" statement in the PHP disappears in the last-menu-item segment.

    If that makes sense…

  4. Tony M says:

    Hey, thank you for this write up. This was exactly what I was looking for.

    Perhaps another caveat is that it will also hide the menu item from Administrator. Yes, it is working properly because the Admin is in a logged in state. So site owners will need to remember that while they are logged in they may forget the other menu elements.

    Cheers and once again, thank you.
    -Tony

  5. Elvis says:

    What worked for me:

    I had tow css classes, named .membersonly and .guestsonly, after that, I added the following to my css:

    .membersonly {display: none;}
    .guestsonly {display: none;}
    body.logged-in .membersonly {display: block;}
    body.not-logged-in .guestsonly {display: block;}

    Now I could use this css classes in my content as well, like
    Please log in first
    Welcome Home!

    Works like a charm for me ;-)

  6. Andrew says:

    You could do this without any PHP. Set logged-in-nav and logged-out-nav classes to your menu items. Then do:

    #menu-mainmenu li.logged-in-nav {
    display: none;
    }

    body.logged-in #menu-mainmenu li.logged-in-nav {
    display: list-item;
    }

    body.logged-in #menu-mainmenu li.logged-out-nav {
    display: none;
    }

    • dave says:

      G’day Andrew, thanks for dropping by and leaving a comment. The purpose of the php edit is to actually add a class to the body tag so that we can bounce off it some css for non-logged-in users. The problem being, to test for a css match on a guest user we need the new class as the body tag has no associated class if the user isn’t logged in.

      Actually, I’ve just gone back over and had another look at your css, and (although I haven’t tried it), I can see how it works. Very clever. I didn’t think of just hiding everything to start with and then bringing it back. Thanks.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="">