Skip to main content

Course Progress

Loading...

Learning Objectives

  • Understand WordPress navigation menu system
  • Register custom menu locations
  • Enable theme support for menus
  • Configure menu location settings
  • Handle fallback menus
  • Manage multiple menu locations
  • Implement menu location checks
  • Use best practices for menu registration

Understanding WordPress Navigation Menus

WordPress navigation menus allow users to create custom menus through the admin interface. Themes must register menu locations where these menus can be displayed.

💡
Key Concept
Menu locations are placeholders in your theme where users can assign menus. A theme can have multiple menu locations, and each location can display different menus.

Enabling Theme Support for Menus

Add Menu Support in functions.php

<?php
/**
 * Theme setup function
 */
function mytheme_setup() {
    // Add theme support for menus
    add_theme_support( 'menus' );
    
    // Other theme supports
    add_theme_support( 'title-tag' );
    add_theme_support( 'post-thumbnails' );
    add_theme_support( 'html5', array( 
        'navigation-widgets',
        'search-form',
        'comment-form',
        'comment-list',
        'gallery',
        'caption'
    ) );
}
add_action( 'after_setup_theme', 'mytheme_setup' );

Registering Menu Locations

Basic Menu Registration

<?php
/**
 * Register navigation menu locations
 */
function mytheme_register_menus() {
    register_nav_menus( array(
        'primary'   => __( 'Primary Menu', 'mytheme' ),
        'secondary' => __( 'Secondary Menu', 'mytheme' ),
        'footer'    => __( 'Footer Menu', 'mytheme' ),
        'social'    => __( 'Social Links Menu', 'mytheme' ),
    ) );
}
add_action( 'after_setup_theme', 'mytheme_register_menus' );

Advanced Menu Registration with Descriptions

<?php
/**
 * Register navigation menus with detailed configuration
 */
function mytheme_register_nav_menus() {
    // Single menu registration
    register_nav_menu( 'primary', __( 'Primary Navigation', 'mytheme' ) );
    
    // Multiple menus with descriptive names
    $locations = array(
        'header-menu'      => __( 'Header Main Menu - Appears in the site header', 'mytheme' ),
        'mobile-menu'      => __( 'Mobile Menu - Displayed on mobile devices', 'mytheme' ),
        'footer-menu'      => __( 'Footer Menu - Links in the footer area', 'mytheme' ),
        'footer-legal'     => __( 'Footer Legal Menu - Copyright and legal links', 'mytheme' ),
        'account-menu'     => __( 'Account Menu - User account related links', 'mytheme' ),
        'social-menu'      => __( 'Social Media Menu - Social network links', 'mytheme' ),
        'top-bar'          => __( 'Top Bar Menu - Utility links above header', 'mytheme' ),
    );
    
    register_nav_menus( $locations );
}
add_action( 'init', 'mytheme_register_nav_menus' );

Common Menu Location Types

Checking and Managing Menu Locations

Check if Menu Location Has Menu

<?php
/**
 * Check if a menu is assigned to a location
 */
function mytheme_check_menu_location() {
    // Check if location has a menu
    if ( has_nav_menu( 'primary' ) ) {
        // Display the menu
        wp_nav_menu( array(
            'theme_location' => 'primary',
            'container'      => 'nav',
            'container_class' => 'primary-navigation',
        ) );
    } else {
        // Display fallback content
        echo '<p>Please assign a menu to the Primary Menu location.</p>';
    }
}

/**
 * Get all registered menu locations
 */
function mytheme_get_menu_locations() {
    // Get all registered locations
    $locations = get_registered_nav_menus();
    
    // Get assigned menu locations
    $menu_locations = get_nav_menu_locations();
    
    foreach ( $locations as $location => $description ) {
        echo '<p>';
        echo 'Location: ' . $location . ' - ' . $description;
        
        if ( isset( $menu_locations[$location] ) ) {
            $menu = wp_get_nav_menu_object( $menu_locations[$location] );
            echo ' (Assigned: ' . $menu->name . ')';
        } else {
            echo ' (No menu assigned)';
        }
        echo '</p>';
    }
}

Conditional Menu Registration

<?php
/**
 * Register menus based on theme options
 */
function mytheme_conditional_menus() {
    // Always register primary menu
    register_nav_menu( 'primary', __( 'Primary Menu', 'mytheme' ) );
    
    // Register additional menus based on theme options
    $theme_options = get_theme_mod( 'mytheme_options', array() );
    
    // Register mega menu if enabled
    if ( ! empty( $theme_options['enable_mega_menu'] ) ) {
        register_nav_menu( 'mega-menu', __( 'Mega Menu', 'mytheme' ) );
    }
    
    // Register footer menus based on footer columns
    $footer_columns = get_theme_mod( 'footer_columns', 3 );
    for ( $i = 1; $i <= $footer_columns; $i++ ) {
        register_nav_menu( 
            'footer-' . $i, 
            sprintf( __( 'Footer Menu Column %d', 'mytheme' ), $i )
        );
    }
    
    // Register language-specific menus for multilingual sites
    if ( function_exists( 'pll_languages_list' ) ) {
        $languages = pll_languages_list();
        foreach ( $languages as $lang ) {
            register_nav_menu(
                'primary-' . $lang,
                sprintf( __( 'Primary Menu (%s)', 'mytheme' ), strtoupper( $lang ) )
            );
        }
    }
}
add_action( 'init', 'mytheme_conditional_menus' );

Useful Menu Location Functions

Function Description Usage
register_nav_menu() Register single menu location register_nav_menu( 'location', 'Description' )
register_nav_menus() Register multiple menu locations register_nav_menus( array() )
has_nav_menu() Check if location has menu if ( has_nav_menu( 'primary' ) )
get_registered_nav_menus() Get all registered locations $locations = get_registered_nav_menus()
get_nav_menu_locations() Get assigned menu locations $menu_locations = get_nav_menu_locations()
unregister_nav_menu() Remove a menu location unregister_nav_menu( 'location' )

Implementing Fallback Menus

Fallback Menu Strategies

<?php
/**
 * Fallback menu function
 */
function mytheme_fallback_menu() {
    // Display page list as fallback
    echo '<nav class="fallback-navigation">';
    echo '<ul class="menu">';
    
    // Add home link
    echo '<li><a href="' . esc_url( home_url( '/' ) ) . '">' . __( 'Home', 'mytheme' ) . '</a></li>';
    
    // List pages
    wp_list_pages( array(
        'title_li' => '',
        'depth'    => 1,
        'number'   => 5,
        'sort_column' => 'menu_order, post_title',
    ) );
    
    echo '</ul>';
    echo '</nav>';
}

/**
 * Display menu with fallback
 */
function mytheme_display_menu() {
    if ( has_nav_menu( 'primary' ) ) {
        wp_nav_menu( array(
            'theme_location' => 'primary',
            'container'      => 'nav',
            'container_class' => 'main-navigation',
            'menu_class'     => 'primary-menu',
            'fallback_cb'    => false, // No fallback
        ) );
    } else {
        // Show fallback menu
        mytheme_fallback_menu();
    }
}

/**
 * Admin notice for missing menus
 */
function mytheme_menu_admin_notice() {
    if ( ! has_nav_menu( 'primary' ) && current_user_can( 'edit_theme_options' ) ) {
        ?>
        <div class="notice notice-warning">
            <p>
                <?php 
                printf(
                    __( 'Your theme has menu locations ready, but no menus have been created yet. <a href="%s">Create a menu</a>.', 'mytheme' ),
                    admin_url( 'nav-menus.php' )
                );
                ?>
            </p>
        </div>
        <?php
    }
}
add_action( 'admin_notices', 'mytheme_menu_admin_notice' );

Best Practices

Menu Registration Best Practices

  • Use descriptive names: Make location purposes clear
  • Internationalize strings: Use __() for translations
  • Register early: Use 'after_setup_theme' or 'init' hook
  • Provide fallbacks: Handle cases when no menu is assigned
  • Check before display: Use has_nav_menu() before outputting
  • Document locations: Add descriptions for users
  • Limit locations: Don't create unnecessary menu locations
  • Consider mobile: Register separate mobile menu if needed
Always check if a menu location has an assigned menu before attempting to display it. This prevents errors and provides better user experience.

Practice Exercise

💻
Register Theme Menu System

Create a comprehensive menu registration system:

  1. Enable theme support for menus
  2. Register primary navigation location
  3. Register footer menu location
  4. Register social links menu
  5. Add mobile-specific menu location
  6. Create fallback menu function
  7. Check if locations have menus
  8. Display admin notice for missing menus
  9. Add conditional menu registration
  10. Test menu locations in Customizer

Additional Resources