WordPress: Navigation Menus

When building a custom WordPress theme you may want to have the ability to maintain the navigation menu(s) from the WordPress Admin Dashboard. You can achieve this using the register_nav_menus() function and wp_nav_menu() function within your theme files:

register_nav_menus()

Open your ‘functions.php’ file in your WordPress theme folder and add the following.

This tells WordPress that you want the ability to control your theme’s navigation menus using the Appearance > Menus tool within the WordPress Admin Dashboard.

// *****************************************************************
//
//  Register your navigation menus
//
//  Enables 'Menus' within the WordPress Admin Dashboard's 'Appearance' menu
//
//  Required for the 'wp_nav_menu' function to work
//
//  Used in the 'template-parts/site-navigation.php'
//  and 'template-parts/site-navigation-footer.php' files
//
// *****************************************************************
function register_navigation() {
  register_nav_menus( array(
    'menu-1' => __( 'Primary Navigation', 'Theme Name' ),
    'menu-2' => __( 'Footer Navigation', 'Theme Name' )
  ) );
}
add_action( 'after_setup_theme', 'register_navigation' );

wp_nav_menu

Open the file that will contain your navigation menu and add the following.

You can customize this quite extensively if needed.

wp_nav_menu( array(
    'theme_location' => 'menu-1', // Enter your menu name
));

Perhaps you want to remove the default <div> element that comes after the <nav> element and before the <ul> element.

wp_nav_menu( array(
    'theme_location' => 'menu-1', // Enter your menu name
    'container' => 'false', // Remove the div wrapper
));

Or perhaps you want to add a custom class to the parent <ul> element.

wp_nav_menu( array(
    'theme_location' => 'menu-1', // Enter your menu name
    'container' => 'false', // Remove the div wrapper
    'menu_class' => 'nav-menu', // Add a class to the parent ul
));

Or you want to add custom classes to all <li> elements or all <a> elements.

wp_nav_menu( array(
    'theme_location' => 'menu-1', // Enter your menu name
    'container' => 'false', // Remove the div wrapper
    'menu_class' => 'nav-menu', // Add a class to the parent ul
    'list_item_class' => 'nav-item', // Add a class to all li elements
    'link_class' => 'nav-link' // Add a class to all a elements
));

Important! The above key value pairs for ‘list_item_class’ and ‘link_class’ above need a bit of additional custom code added to your functions.php file:

// ***********************************
// 
//  Add custom classes to 'wp_nav_menu' li elements
// 
//  Used in the 'template-parts/site-navigation.php'
//  and 'template-parts/site-navigation-footer.php' files
// 
// ***********************************
function add_menu_list_item_class($classes, $item, $args) {
  if (property_exists($args, 'list_item_class')) {
      $classes[] = $args->list_item_class;
  }
  return $classes;
}
add_filter('nav_menu_css_class', 'add_menu_list_item_class', 1, 3);

// ***********************************
// 
//  Add custom classes to 'wp_nav_menu' a elements
//
//  Used in the 'template-parts/site-navigation.php'
//  and 'template-parts/site-navigation-footer.php' files
// 
// ***********************************
function add_menu_link_class( $atts, $item, $args ) {
  if (property_exists($args, 'link_class')) {
    $atts['class'] = $args->link_class;
  }
  return $atts;
}
add_filter( 'nav_menu_link_attributes', 'add_menu_link_class', 1, 3 );

WordPress Admin Dashboard:
Appearance > Menus

Now you can log in to your WordPress Admin Dashboard and you’ll find a new feature within the “Appearance” dropdown called “Menus”.

It should have any menus that you registered within the register_nav_menus() function available to be configured however you’d like.