{"id":917,"date":"2020-07-16T10:56:53","date_gmt":"2020-07-16T14:56:53","guid":{"rendered":"http:\/\/tech.creed3.com\/?p=917"},"modified":"2020-07-16T10:56:53","modified_gmt":"2020-07-16T14:56:53","slug":"wordpress-conditional-menus-without-a-plugin","status":"publish","type":"post","link":"https:\/\/tech.creed3.com\/?p=917","title":{"rendered":"WordPress Conditional Menus Without A Plugin"},"content":{"rendered":"<p><img decoding=\"async\" style=\"margin: 0 0 4px 4px;\" alt=\"\" src=\"images\/stories\/wordpress-logo-simplified-rgb.png\" width=\"100\" align=\"right\" border=\"0\" \/>Have you ever wished you could have your navigation menu change depending on whether a user is logged in or not? &nbsp;For a logged in user they would see a logout option and maybe a link to their profile. &nbsp;Whereas those not logged in would be offered a login menu link. &nbsp;Sounds simple enough.<!--more--><\/p>\n<p>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. &nbsp;It gives the user a better visual experience to be sure, and keeps them out of the admin area, which could get messy. &nbsp;I really like the plugin, it&#8217;s simple and adds very little overhead, but there&#8217;s no way of allowing for changing menus for logged in users or guests. &nbsp;I was sure there had to be a way to do this so I went looking.<\/p>\n<p>Right now you might be thinking &#8220;just use the built in meta menu&#8221;. &nbsp;Yes, you can do that. &nbsp;But I never really liked it, do you? &nbsp;Oh sure there are plugins to modify it which of course adds another plugin to your site. &nbsp;This is actually what I do on this site but that may be changing real soon. &nbsp;There are several plugins that can help you with displaying different menus depending on who is logged in or not, and if you&#8217;re using one of the many membership plugins you probably already have this function built-in with that. &nbsp;But what if your plugin doesn&#8217;t have this option? &nbsp;Or what if you simply would like to allow this without using yet another resource heavy plugin?<\/p>\n<p><strong>Plug In or Out?<\/strong><br \/>\nDon&#8217;t get me wrong I like plugins just fine. &nbsp;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. &nbsp;Many themes do this as well, especially those that rely on resource hogging frameworks. &nbsp;Use a child theme and it only adds to the problem. &nbsp;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.<\/p>\n<p>In the course of coding WordPress themes or plugins I often turn to the web to find answers. &nbsp;There&#8217;s no shortage of blogs and forums out there addressing all things WordPress and most of the time I can find what I&#8217;m looking for fairly quickly. &nbsp;But I am beginning to see most &#8220;solutions&#8221; to a problem rely more and more on plugins. &nbsp;That&#8217;s great for those who do not want to get into coding everything. &nbsp;But what if you understand code and want to do something without the added hit of yet another plugin?<\/p>\n<p><strong>Conditional Menus<\/strong><br \/>\nThere are many reasons to want conditional menus other than the scenario I had. &nbsp;You could provide anyone with direct access to where they need to be based on their user access level. &nbsp;That is somewhat the function of the admin bar at the top when you&#8217;re logged in, but this can be more granular. &nbsp;And maybe you don&#8217;t want your authors poking around in the admin area, so you disable the admin bar and give them links in a menu.<\/p>\n<p>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. &nbsp;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. &nbsp;This solution actually dawned on me while reviewing one of those hook functions. &nbsp;The <em>only<\/em> caveat is you&#8217;ll need to edit a sidebar file directly. &nbsp;If you&#8217;re using your own custom theme this is no problem. &nbsp;If you aren&#8217;t you may want to carefully consider doing this, as the next time your theme updates your menus will break.<\/p>\n<p>In directly editing the theme sidebar file where you want your menu to appear, you&#8217;re taking advantage of the fact that your sidebar is already being registered so there will be no extra load on your site. &nbsp;We will be calling the built in menu function and telling it to load a specific menu based on the user login credentials. &nbsp;This adds no new functions or hooks and simply by utilizes what WordPress is already doing and already &#8220;knows&#8221; about the user to make the &#8220;decision&#8221; between menus.<\/p>\n<p>Your theme most likely is registering your sidebar files, and should also be registering menus as well, all in your functions.php file. &nbsp;We will be adding to the menu registration function, but that&#8217;s it. &nbsp;In my case here&#8217;s how I modified the menu registration in my theme functions.php file.<\/p>\n<pre><code style=\"font-size:12px;\">\/\/ BEFORE\r\nfunction register_menus() {\r\n  register_nav_menus(\r\n  &nbsp; array(\r\n  &nbsp;  &nbsp;'main-menu' =&gt; __( 'Main Menu' )\r\n  &nbsp; )\r\n  );\r\n}\r\nadd_action( 'init', 'register_menus' );\r\n\r\n\/\/ AFTER\r\nfunction register_menus() {\r\n  register_nav_menus(\r\n  &nbsp; array(\r\n  &nbsp;  &nbsp;'main-menu' =&gt; __( 'Main Menu' ),\r\n  &nbsp;  &nbsp;'user-menu' =&gt; __( 'User Menu' ),\r\n  &nbsp;  &nbsp;'guest-menu' =&gt; __( 'Guest Menu' )\r\n  &nbsp; )\r\n  );\r\n}\r\nadd_action( 'init', 'register_menus' );<\/code><\/pre>\n<p>As you can see I added two new menus to my theme, &#8216;User Menu&#8217; and &#8216;Guest Menu&#8217;. &nbsp;That&#8217;s it, we&#8217;re done with the functions.php file.<\/p>\n<p>Next, head over to Dashboard > Appearance > Menus.<\/p>\n<p>You probably already have a &#8220;main&#8221; menu for your site and it should be assigned to your main menu area. &nbsp;In this example you need to add two additional menus, one named &#8216;guest-menu&#8217; and the other named &#8216;user-menu&#8217;. &nbsp;The guest-menu has only a login link and should be assigned to the Guest Menu theme location. &nbsp;The user-menu has a logout and profile link and should be assigned to the User Menu theme location.<\/p>\n<p>We are done with menus.<\/p>\n<p>Now open the sidebar file where your main menu is called. &nbsp;IF you are placing your menu as a widget, once we&#8217;re done with this you&#8217;ll want to disable or remove that widget. &nbsp;For now, if you are already calling the main menu in your sidebar file it should look something like this:<\/p>\n<pre><code style=\"font-size:12px;\">&lt;div id=\"sidebar-left\"&gt;\r\n&lt;ul&gt;\r\n&lt;?php wp_nav_menu( array( 'theme_location' =&gt; 'main-menu' ) ); ?&gt;\r\n&lt;?php if ( function_exists ( dynamic_sidebar('left') ) ) : ?&gt;\r\n&lt;?php dynamic_sidebar ('left'); ?&gt;\r\n&lt;?php endif; ?&gt;\r\n&lt;\/ul&gt;\r\n&lt;\/div&gt;<\/code><\/pre>\n<p>If you aren&#8217;t placing your main menu with a function call in the sidebar, but rather as a widget, you&#8217;ll want to add the <\/p>\n<pre><code>&lt;?php wp_nav_menu( array( 'theme_location' =&gt; 'main-menu' ) ); ?&gt;<\/code><\/pre>\n<p> function call to your sidebar file. &nbsp;Just make certain it&#8217;s BEFORE the dynamic_sidebar() function call or your menu will not display, this is important.<\/p>\n<p>Now let&#8217;s add the conditional part. &nbsp;We&#8217;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. &nbsp;You can place this decision making routine before or after your main menu which ever you prefer. &nbsp;I placed mine after the main menu. &nbsp;So the final code for the sidebar will look like this:<\/p>\n<pre><code style=\"font-size:12px;\">&lt;div id=\"sidebar-left\"&gt;\r\n&lt;ul&gt;\r\n&lt;?php\r\nwp_nav_menu( array( 'theme_location' =&gt; 'main-menu' ) );\r\nif( is_user_logged_in() ) {\r\n  &nbsp; wp_nav_menu( array( 'theme_location' =&gt; 'user-menu' ) );\r\n} else { \r\n  &nbsp; wp_nav_menu( array( 'theme_location' =&gt; 'guest-menu' ) );\r\n}\r\n?&gt;\r\n&lt;?php if ( function_exists ( dynamic_sidebar('left') ) ) : ?&gt;\r\n&lt;?php dynamic_sidebar ('left'); ?&gt;\r\n&lt;?php endif; ?&gt;\r\n&lt;\/ul&gt;\r\n&lt;\/div&gt;<\/code><\/pre>\n<p>That&#8217;s it. &nbsp;Place your edited functions and sidebar files on your server in your theme&#8217;s folder and you should see your new conditional menus.<\/p>\n<p>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. &nbsp;It&#8217;s a solution that works well IF you build your own theme and it keeps the overhead cost of your site lower.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Have you ever wished you could have your navigation menu change depending on whether a user is logged in or not? &nbsp;For a logged in user they would see a logout option and maybe a link to their profile. &nbsp;Whereas those not logged in would be offered a login menu link. &nbsp;Sounds simple enough.<\/p>\n","protected":false},"author":9,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[16,30,41],"tags":[],"class_list":["post-917","post","type-post","status-publish","format-standard","hentry","category-technology","category-web-development","category-wordpress"],"views":1812,"_links":{"self":[{"href":"https:\/\/tech.creed3.com\/index.php?rest_route=\/wp\/v2\/posts\/917","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tech.creed3.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tech.creed3.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tech.creed3.com\/index.php?rest_route=\/wp\/v2\/users\/9"}],"replies":[{"embeddable":true,"href":"https:\/\/tech.creed3.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=917"}],"version-history":[{"count":0,"href":"https:\/\/tech.creed3.com\/index.php?rest_route=\/wp\/v2\/posts\/917\/revisions"}],"wp:attachment":[{"href":"https:\/\/tech.creed3.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=917"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tech.creed3.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=917"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tech.creed3.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=917"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}