WordPress Register Nav Menus

To let a site owner build a menu in the dashboard and show it in your theme, you do two things: register the menu locations, and call wp_nav_menu() in the template.

Register locations

<?php
function tc_theme_setup() {
	add_theme_support( 'title-tag' );
	register_nav_menus( array(
		'primary' => 'Primary Menu',
		'footer'  => 'Footer Menu',
	) );
}
add_action( 'after_setup_theme', 'tc_theme_setup' );

Print the menu

In header.php call wp_nav_menu() with the location name:

<?php
wp_nav_menu( array(
	'theme_location' => 'primary',
	'container'      => 'nav',
	'menu_class'     => 'main-menu',
	'fallback_cb'    => false,
) );
?>

Create the menu and assign it

The site owner does it in Appearance > Menus. With WP-CLI it takes few commands:

Terminal output

$ wp menu location list
location description
primary Primary Menu
footer Footer Menu
$ wp menu create "Main Menu"
Success: Created menu 2.
$ wp menu item add-post main-menu 2 –title="About"
Success: Menu item added.
$ wp menu item add-custom main-menu "Blog" http://example.com/blog/
Success: Menu item added.
$ wp menu location assign main-menu primary
Success: Assigned location primary to menu main-menu.
$ wp menu list –fields=name,slug,locations
name slug locations
Main Menu main-menu primary
$ curl -s http://example.com/ | sed -n '/<nav/,/<\/nav>/p' | sed 's/^[ \t]*//'
<nav class="menu-main-menu-container"><ul id="menu-main-menu" class="main-menu"><li id="menu-item-5" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-5"><a href="http://example.com/sample-page/">About</a></li>
<li id="menu-item-6" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-6"><a href="http://example.com/blog/">Blog</a></li>
</ul></nav><main>

Main arguments of wp_nav_menu()

ArgumentMeaning
theme_locationThe location registered with register_nav_menus()
menuA menu name, ID or slug (instead of location)
container, container_classThe wrapper tag (div or nav) and its class
menu_class, menu_idThe class and ID of the ul list
depthHow many levels to show (0 means all)
fallback_cbA function to run when no menu is set. false shows nothing
walkerA custom class for full control of the HTML
Note: WordPress adds classes like current-menu-item to the active link, so you can style it in CSS. Use has_nav_menu( 'primary' ) to check if a menu is assigned before you print the wrapper. Next: Actions and Filters.

Congratulations! Chapter Finished. Learn more about the similar topics:
Exercises & Assignments
Create a navigation menu with three links
Register a sidebar and show a widget in it
Interview Questions & Answers
What menu positions and order are available in WordPress?
What are widgets in WordPress?