How To Create New WordPress Custom Menu

  • follow us in feedly
Published April 14, 2013 by Brad Knutson
WordPress Custom Menu

Many new WordPress themers come to a point where they need to add new custom menu locations in their theme. The process to register and initialize a menu is pretty easy, and I’ll go over it in detail below.

First, we need to register the new menu. The built-in register_nav_menu() function is one we’ll use for registering a single new menu. Below is the default usage of the function.

<?php register_nav_menu( $location, $description ); ?>

The parameters $location and $description are both required. $location is the menu location identifier. For all intents and purposes, it’s a slug. Typically I’ll just use slug version of whatever I enter in the $description variable. The $description variable is a short description of the menu. This will be displayed in the WordPress admin on the Appearance > Menus page.

The function is placed in your functions.php file. As an example, I registered my own menu and called it “Secondary Menu.”

register_nav_menu( 'secondary-menu', 'Secondary Menu' );

WordPress Custom Menu Description

As you see, after pasting the function into my themes functions.php file, the new menu is available on the Menus page in the WordPress admin. From this page, we can add any nodes to the menu we want, just like any other menu.

Note: To register multiple menus at once, we’ll use a slightly different built-in function and the same parameters.

register_nav_menus( $locations = array() );

Now we need to add this menu to our theme template file(s). We’ll again use a built-in WordPress function, whose default usage I’ve pasted below.

<?php wp_nav_menu( $args ); ?>

This function comes with many more parameters. Here are defaults.


$defaults = array(
	'theme_location'  => '',
	'menu'            => '',
	'container'       => 'div',
	'container_class' => '',
	'container_id'    => '',
	'menu_class'      => 'menu',
	'menu_id'         => '',
	'echo'            => true,
	'fallback_cb'     => 'wp_page_menu',
	'before'          => '',
	'after'           => '',
	'link_before'     => '',
	'link_after'      => '',
	'items_wrap'      => '<ul id="%1$s" class="%2$s">%3$s</ul>',
	'depth'           => 0,
	'walker'          => '');
wp_nav_menu( $defaults );
  • $theme_location – (string) (optional) The location in the theme to be used–must be registered with register_nav_menu() in order to be selectable by the user
  • $menu – (string) (optional) The menu that is desired; accepts (matching in order) id, slug, name
  • $container – (string) (optional) Whether to wrap the ul, and what to wrap it with. Allowed tags are div and nav. Use false for no container e.g. 'container' => false
  • $container_class – (string) (optional) The class that is applied to the container
  • $container_id – (string) (optional) The ID that is applied to the container
  • $menu_class – (string) (optional) The class that is applied to the ul element which encloses the menu items. Multiple classes can be separated with spaces. Formerly known as $wrap_class.
  • $menu_id – (string) (optional) The ID that is applied to the ul element which encloses the menu items. Formerly known as $wrap_id.
  • $echo – (boolean) (optional) Whether to echo the menu or return it. For returning menu use ‘0’
  • $fallback_cb – (string) (optional) If the menu doesn’t exist, the fallback function to use. Set to false for no fallback. Note: Passes $args to the custom function.
  • $before – (string) (optional) Output text before the <a> of the link
  • $after – (string) (optional) Output text after the </a> of the link
  • $link_before – (string) (optional) Output text before the link text
  • $link_after – (string) (optional) Output text after the link text
  • $items_wrap – (string) (optional) Evaluated as the format string argument of a sprintf() expression. The format string incorporates the other parameters by numbered token. %1$s is expanded to the value of the ‘menu_id’ parameter, %2$s is expanded to the value of the ‘menu_class’ parameter, and %3$s is expanded to the value of the list items. If a numbered token is omitted from the format string, the related parameter is omitted from the menu markup.
  • $depth – (integer) (optional) How many levels of the hierarchy are to be included where 0 means all. -1 displays links at any depth and arranges them in a single, flat list.
  • $walker – (object) (optional) Custom walker object to use (Note: You must pass an actual object to use, not a string)

That looks like a lot, doesn’t it? Really though, we only need to use a few of the parameters if we want to, the other are optional and used to make styling the menu easier. To display the new menu, add the below code into your theme template file wherever you want the menu to display.

<?php wp_nav_menu( array( 'menu' => 'slug', 'container_class' => 'nav' ) ); ?>

We use the menu parameter, and use the slug value of $location from the original register_nav_menu() function. The container_class, or some other parameter, can be used to add classes to the container elements in order to easily style the menu.

The following two tabs change content below.
Founder at Inbounderish
Brad Knutson is a Web Developer in the Twin Cities area of Minnesota. He has experience working with WordPress and Drupal, and also has an interest in SEO and Inbound Marketing.

Keep Up-to-Date



See a complete list of topics discussed in blog posts here.

Check These Out

Get 2 Weeks Free! Sign Up Today! Premium Managed WordPress Hosting Genesis Framework for WordPress SEO is complex. Tools should be simple. Thesis Theme for WordPress:  Options Galore and a Helpful Support Community

Share Your Thoughts

Your email address will not be shown.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">