函数文档

register_nav_menus()

💡 云策文档标注

概述

register_nav_menus() 函数用于为主题注册多个导航菜单位置,通过关联数组定义菜单标识符和描述文本。它自动启用菜单主题支持,无需额外调用 add_theme_support('menus')。

关键要点

  • 参数 $locations 为可选关联数组,键为菜单位置标识符(如 slug),值为描述文本,默认为空数组
  • 函数内部自动调用 add_theme_support('menus'),简化主题开发流程
  • 使用 wp_nav_menu() 来显示已注册的菜单,get_registered_nav_menus() 可获取已注册菜单列表
  • 在管理后台的菜单页面,可启用“显示高级菜单属性”以配置链接目标、CSS 类等选项
  • 注意菜单标识符必须为字符串,否则会触发 _doing_it_wrong() 警告

代码示例

register_nav_menus( array(
    'primary_menu' => __( 'Primary Menu', 'text_domain' ),
    'footer_menu'  => __( 'Footer Menu', 'text_domain' ),
) );

注意事项

  • 修改已注册菜单的 slug 时,需在后台重新分配菜单,或使用自定义函数更新主题设置以避免前端菜单消失
  • 确保在 after_setup_theme 钩子中调用 register_nav_menus(),以正确集成到主题初始化过程

📄 原文内容

Registers navigation menu locations for a theme.

Parameters

$locationsstring[]optional
Associative array of menu location identifiers (like a slug) and descriptive text.

Default:array()

More Information

See register_nav_menu() for creating a single menu, and Navigation Menus for adding theme support.

This function automatically registers custom menu support for the theme, therefore you do not need to call add_theme_support( 'menus' );

Use wp_nav_menu() to display your custom menu.

On the Menus admin page, there is a Show advanced menu properties to allow “Link Target” “CSS Classes” “Link Relationship (XFN) Description”

Use get_registered_nav_menus to get back a list of the menus that have been registered in a theme.

Source

function register_nav_menus( $locations = array() ) {
	global $_wp_registered_nav_menus;

	add_theme_support( 'menus' );

	foreach ( $locations as $key => $value ) {
		if ( is_int( $key ) ) {
			_doing_it_wrong( __FUNCTION__, __( 'Nav menu locations must be strings.' ), '5.3.0' );
			break;
		}
	}

	$_wp_registered_nav_menus = array_merge( (array) $_wp_registered_nav_menus, $locations );
}

Changelog

Version Description
3.0.0 Introduced.

User Contributed Notes

  1. Skip to note 6 content

    if ( ! function_exists( 'mytheme_register_nav_menu' ) ) {
    
    	function mytheme_register_nav_menu(){
    		register_nav_menus( array(
    	    	'primary_menu' => __( 'Primary Menu', 'text_domain' ),
    	    	'footer_menu'  => __( 'Footer Menu', 'text_domain' ),
    		) );
    	}
    	add_action( 'after_setup_theme', 'mytheme_register_nav_menu', 0 );
    }

  2. Skip to note 7 content

    Refactoring Menu Slugs:

    If you just rename the slug of a registered menu location, it will disappear from the frontend. This means you need to reassign the menu to the new location in the dashboard.

    In order to edit the slug of a menu location while automatically keeping the previously assigned menu, customize and use the following snippet after renaming the slug in register_nav_menu():

    function cebbi_update_menu_location() {
    
    	// Get assigned menus from theme mods
    	$nav_menu_locations = get_theme_mod('nav_menu_locations');
    
    	// Check if old-slug was previously assigned
    	if (isset($nav_menu_locations['old-slug'])) {
    
    		// Verify that new location does not yet exist or is empty to avoid overwriting manual changes
    		if (!isset($nav_menu_locations['new-slug']) || $nav_menu_locations['new-slug'] === 0) { 
    
    			// Copy assigned menu index to new location
    			$nav_menu_locations['new-slug'] = $nav_menu_locations['old-slug'];
    
    			// Optional: delete the menu assignment to the old location
    			unset($nav_menu_locations['old-slug']);
    
    			// Update theme mod
    			set_theme_mod('nav_menu_locations', $nav_menu_locations);
    		}
    	}
    }
    add_action('after_setup_theme', 'cebbi_update_menu_location');

    Also, don’t forget to update the slug where it’s used to display the menu (wp_nav_menu(), has_nav_menu()).

    You can use get_registered_nav_menus() to verify that the old-slug is not registered in your theme, before removing the assigned menu.

  3. Skip to note 9 content

    Creating menus from your Custom Taxonomies.

    For example: I have a custom taxonomy named ‘Country’ with a few countries in list.
    Right now I want to assign each country has a private name and using it for condition displayed on frontend.

    $tax = 'country-category';
    
    $terms = get_terms( $tax, [
    'hide_empty' => false,
    ]);
    
    $args = array(
    'primary' => __( 'Primary Menu', 'khoipro' ),
    'secondary' => __( 'Secondary Menu', 'khoipro' )
    );
    
    // Loop through all terms to add term id as menu id and term name as menu name.
    foreach( $terms as $term) {
    $args = array_merge($args, array(
    'primary_'.$term->slug => 'Country Menu ('.$term->name.')'
    ));
    }
    
    register_nav_menus( $args );

    So my output codes should be displayed in Menus > Manage Locations:

    * Primary Menu (id: primary)
    * Secondary Menu (id: secondary)
    * Country Menu (Japan) (id: primary_japan)
    * Country Menu (Singapore) (id: primary_singapore)
    * Country menu (Vietnam) (id: primary_vietnam)

    Have a proof in a real practice with a newly created project.