Link to home
Start Free TrialLog in
Avatar of steva
steva

asked on

How to implement a conditional menu destination in WordPress

I have a standard menu at the top of my WordPress pages and I'd like the "Home" tab to go one place if the user is logged in and to another place if the user is not logged in.

Thanks for any ideas.
Avatar of William Nettmann
William Nettmann
Flag of South Africa image

I have used this snippet to do something similar:
function add_login_logout_register_menu( $items, $args ) {
	if ( $args->theme_location != 'primary' ) {
		return $items;
	}
 
	if ( is_user_logged_in() ) {
		$items .= '<li><a href="' . wp_logout_url() . '">' . __( 'Log Out' ) . '</a></li>';
	} else {
		$items .= '<li><a href="' . wp_login_url() . '">' . __( 'Login In' ) . '</a></li>';
		$items .= '<li><a href="' . wp_registration_url() . '">' . __( 'Sign Up' ) . '</a></li>';
	}
 
	return $items;
}
 
add_filter( 'wp_nav_menu_items', 'add_login_logout_register_menu', 199, 2 );

Open in new window

You will need to add a "Home Page" link to a custom menu using the Appearance -> Menus option in WordPress, and use a placeholder instead of a URL, e.g. "#dynamic-link". You can then do a "str_replace" on the string in the "$items" string in the function instead of adding the login / logout link at the end.
Avatar of steva
steva

ASKER

Hi William,

It seems that what I want to do in my filter function is find the "Home" li in $items and then change its href to the new "Home" if ( is_user_logged_in()).    Is it clear to you how to do that?

Thanks
Yes, it is clear.

Give the "Home" link a placeholder URL, e.g. "##home##"

In the filter:
$real_url = is_user_logged_in() ? "http://example.com/logged-in" : "http://example.com/logged-out";
$items = str_replace("##home##",$real_url,$items);
return $items;

Open in new window

Job done.
Avatar of steva

ASKER

Thank you!  I looked hours last night for documentation on how to bust open the $items objects and work with them,  and finally I thought, "You, know?  I'll bet William could do this in about a minute!"

You're the best!

But it's still not clear to me exactly what you're doing.  The first parameter to str_replace is the thing to search for and you've got "##home##".   How does  that find the highlighted <li> element below and how does the $real_url filled in line 1 work as a replacement for that in the menu?

 Thanks

SteveUser generated image
ASKER CERTIFIED SOLUTION
Avatar of William Nettmann
William Nettmann
Flag of South Africa image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of steva

ASKER

Got it!  I ended up with:
User generated imageUser generated image
Many thanks!
Avatar of steva

ASKER

Thank you again.  A very useful tool to add to my toolbox!
Pleasure, Steve.

Looking at your screenshot above, you could have just added two links to the menu, one for logged in users and one for logged out users.
Avatar of steva

ASKER

Yes.  Put in two menu tabs, both with the "Home" navigation label, and have one go to "Homepage" and the other gp to "login_home."  Then click "Logged In Users" for one and "Logged Out Users" for the other in Display mode. Thanks for that.