The other day I needed to add Login/Logout links to a WordPress menu. Specifically I wanted it to say “Log In” if the user is not logged in, and “Log Out” if the user is logged in. And I want it to appear at the end of the menu I have in the footer (what I’m about to show you will also work for the main navigation menu at the top if you want it to).
As far as creating the Login/out links go, WordPress already has a function that will display the proper link depending on whether a user is logged in or out: wp_loginout() – it’s located in wp-includes/general-template.php.
Now if all I wanted to do was put a Login/out link somewhere on my page, I could easily do that – maybe put it in footer.php or header.php. Just add wp_loginout(); and voila I’m done! But I want it to be part of a menu item which means doing a little more work (and we can do it all in functions.php alone).
Specifically, the site I was working on had 3 menus. 1. Top Navigation, 2. Footer Menu and 3. Sidebar Menu. I only needed to add the Login/out links to the Footer menu.
To do this we need to add a filter. Filters in WordPress are basically ways of “intercepting” processes and making changes to them before they get displayed on the browser. You can read more about filters here: http://codex.wordpress.org/Function_Reference/add_filter
So here’s the thought process of my task thus far:
- We need to somehow get ONLY the footer menu before it’s displayed to the browser
- We need to run wp_loginout() to generate the appropriate links for Log in or Log out
- We need to append those links to the footer menu ( as list items, menu’s in WP are always lists)
- We need to return the new menu list (with our login/out links) back to the page to be displayed
As I mentioned before, the add_filter() function handles this inside our functions.php file. Let’s cut to the chase and then I’ll explain how it all works after. Here’s the code I used:
If you add this to your functions.php file it should do the trick. NOTE: you must specify the menu name in there so that the filter knows WHICH MENU it’s supposed to add the links to.
Well I’m running out of time so I’m going to have to wrap this up. Here’s a quick description on what the code is doing: (It basically follows the thought proces I listed above)
First we use the “if” statement to send back any menu items which are not related to what we want, in my case I only wanted to change “footer-menu”. If it’s not that, send it back just the way it is.
Then we create the link and put it into a variable: $link. Remember, we’re using the wp_loginout() function that WordPress already provides so we don’t need to mess with any additional code. You can read more about how it works in the link above, or here it is again: wp-includes/general-template.php.
Next, we “return” everything with our Login/Logout links appended, and add some proper tags so it fits nicely in our list
The last thing we need to do is call the function we created with the add_filter() function. I’ll briefly go over the first two arguments inside add_filter(). The first one is ‘wp_nav_menu_items’ which tells WordPress that we want to add a filter to the menu items (it goes and “gets” the items). Notice that ‘add_loginout_menu_to_footer’ is the exact same name as the function we created. You probably guessed why, because the second argument in add_filter() is which function we’re sending the first element into. In other words, we’re telling WordPress to intercept the menu items (wp_nav_menu_items) and send them to the function we made (add_loginout_menu_to_footer) before displaying on the browser. The numbers after that are for ordering and sorts. Don’t worry about that for now.
Well I’m outta time. I hope that was useful for you. If you have any questions, please let me know below. Hasta!
2 responses to “How To Add Custom Login/out Links to WordPress Menus”
Line 6 : if ( is_admin() || $args->theme_location != ‘footer-menu’ )
returns an error. It doesn’t like $args-> in the middle of the php, for obvious reasons. Care to post a fix?
Thanks for catching that. When I transferred the code to my new snippets editor it somehow converted all my arrows to text. I fixed and updated it.