Why WordPress Main Menu Navigation is Missing from Categories

Often I am converting old WordPress sites or working with custom page or post types. When you try to force something other than posts to show in category pages, the main navigation menus fail to display. The core WordPress wp_nav_menu() function doesn’t know what to do in those cases and returns nothing.

Code Solution:

if(is_category()) {
$thiscat_id=get_query_var('cat');
$backup=$wp_query;
$wp_query = NULL;
$wp_query = new WP_Query(array('post_type' => 'any'));  }
wp_nav_menu( $defaults );
if($thiscat_id!="") { $wp_query=$backup; }

Many solutions on the web try to include the custom post types in categories or they restrict categories to only display posts by using a new WP_Query. The problem is that then the category page shows all the posts in the website on the page and none of the pages or custom post types. What you want is the filtered results for the category you’re looking at, either including only a custom “post_type” like “page” or all of them (e.g. attachments and the like)—depending on whatever you have assigned to a category.

When I search Google for the phrase “wordpress wp_nav_menu not showing for page categories“, the best solution was jian118’s comment on WordPress.org’s forum. He geniously stores the original query into a “$backup” variable before executing a new one. Here is jian118’s code in case they take the post down in the future:

if(!getMainMenu()){
$backup=$wp_query;
$wp_query = NULL;
$wp_query = new WP_Query(array('post_type' => 'post'));
getMainMenu();
$wp_query=$backup;}

Essentially, wp_nav_menu() doesn’t work when the query for a page uses a post type other than posts AND is filtered by category.

The only way to solve this (at least for WordPress versions up to 3.8), you have to call a new query prior to the menu that only includes posts. Do not filter by category or anything else. You’ll never display that query on the page.

Once the menu has been built on the page, you can display the original filtered results that only includes posts/pages with category set. All you do is simply reset the $wp_query variable with the $backup AFTER the menu code.

The problem with this approach is that after creating a new query WordPress no longer knows you are trying to display a category page. If you try to simply reassign the $wp_query variable after the menu and don’t have a way to do this only for category pages, then that query will show on all pages, no matter what the visitor clicked on prior to the page anywhere on the site.

Code Rationale:

So, above is my code to use in place of just the wp_nav_menu() function. It makes sure these changes only apply to categories. Prior to calling the new query, WordPress knows it’s a category page. You can create a new variable at that point that will trigger the reassigning of the query after the menu is built. Tag pages will likely have the same issue. So if you want it to apply this for tags, simply add “|| is_tag()”in the “if” portion of the formula.

Glad to help people out with this. Good luck!

Leave a Reply