Hide and seek with WordPress menus

WordPress 3.0 introduced a very useful feature: custom menus: if your theme handles it, you can add menus in different areas of your theme, without having to dive into code or install any plugin.

There is only one limitation to this: your menu is often added to your theme’s header or footer and the menu items remain the same on all pages of your site.

Let’s see how to work around this problem, and have different menu items depending on the page you’re on.

Through a plugin (for WordPress.org users only)

If you are using the self-hosted version of WordPress, you could probably find a plugin that allows you to specify different menus on each one of your pages. I won’t cover this solution here: you can probably find a good plugin by browsing the plugin repository.

By customizing your theme (for WordPress.org users only)

If you have access to your theme files, you could look for wp_nav_menu() in your theme, and wrap it in a conditional tag, like so:

<?php
	if (is_home()) {
		wp_nav_menu( array( 'theme_location' => 'home_menu' )  );
	} else {
		wp_nav_menu( array( 'theme_location' => 'general_menu' ) );
	}
?>

Of course, you will need to register these 2 menu locations first, by adding the following code to the functions.php file in your theme:

<?php
	register_nav_menus( array(
		'home_menu' => 'Home Menu',
		'general_menu' => 'General Menu'
	) );
?>

You now have 2 different menu locations, and can assign a different menu to each one of them:

Theme Locations module

The first menu (home_menu) will be displayed on your home page, and your other menu will appear on all the other pages.

You can also use other conditional tags to display specific menus on certain pages or posts, or on your Archive pages. You can find more information about conditional tags here:

But what if you can’t change your theme files?

Through CSS (for WordPress.org and WordPress.com users)

While both of these solutions work, they are not applicable for WordPress.com users, or for users who do not wish to dive into PHP. Let’s consider a third solution, a bit easier. We will use one menu, but hide some of the menu items on some of your pages.

  • If you are a WordPress.com user, you will need to purchase the Custom Design upgrade, available under Appearance > Custom Design in your dashboard. Read more about the Custom Design upgrade here.
  • If you use the self-hosted version of WordPress, you can edit your theme’s stylesheet, or use a plugin like Custom CSS.

Start by going to Appearance > Menus in your dashboard, and enable CSS classes in your screen options:

WordPress Menus' Screen options

A new field appears under each one of your menu items, allowing you to specify a custom CSS class. In the example below, I have added the page-item class to one of the menu items, but didn’t add any CSS class to the Home link.

WordPress menu CSS class

Once you have saved your changes, add the following code to your stylesheet:

.page-item {
	display:list-item;
}
.home .page-item {
	display:none;
}

The first CSS rule displays the menu items on all pages. The second rule has a higher CSS specificity and will add an exception for the home page: the menu items won’t be displayed there.

If you have some issues understanding the CSS code above, you can read more about CSS specificity here: CSS Specificity: Things You Should Know

To define different rules, you can add more CSS classes to your menu items, and use different body classes to hide or show items on specific pages.
You can find a list of all the body classes you can use here: body_class values

There you have it: 3 simple ways to customize your menus on your WordPress site.

Questions? Remarks? Hit me in the comments!

Published by

Jeremy

Happiness Engineer at Automattic. WordPress addict, Internet Junkie. You have been warned.