当前浏览:首页 / WordPress函数 / wp_nav_menu()

wp_nav_menu( array $args = array() )

显示导航菜单

menumore...

nav


参数

$args

(array) (可选) 导航菜单参数数组。

  • 'menu'
    (int|string|WP_Term) 要显示的菜单,接受菜单 ID, slug, name, 或 object.
  • 'menu_class'
    (string) 构成菜单的ul元素的CSS类,默认 'menu'.
  • 'menu_id'
    (string) 构成菜单的ul元素的ID,默认为菜单slug,递增。
  • 'container'
    (string) 是否包住ul,以及用什么包住它,默认为 'div'.
  • 'container_class'
    (string) 应用于容器的类,默认 'menu-{menu slug}-container'.
  • 'container_id'
    (string) 应用于容器的ID
  • 'container_aria_label'
    (string) 当容器是一个导航元素时,应用于容器的aria-label属性
  • 'fallback_cb'
    (callable|false) 如果菜单不存在,将触发回调函数,默认是'wp_page_menu'。设置为false表示没有回调。
  • 'before'
    (string) 链接标记前面的文本
  • 'after'
    (string) 链接标记后面的文本
  • 'link_before'
    (string) 链接文本前面的文本
  • 'link_after'
    (string) 链接文本后面的文本
  • 'echo'
    (bool) 是否输出菜单或只是返回,默认 true.
  • 'depth'
    (int) 包含多少层级菜单, 0表示全部,默认0.
  • 'walker'
    (object) 自定义walker类的实例
  • 'theme_location'
    (string) 要使用的主题位置,必须用register_nav_menu()注册,以便用户可以选择。
  • 'items_wrap'
    (string) 列表项应该如何被包装,使用带编号占位符的printf()格式。默认是一个带有id和class的ul。
  • 'item_spacing'
    (string) 是否在菜单的HTML中保留空白。接受 'preserve' 或 'discard'. 默认 'preserve'.

默认值: array()


返回

(void|string|false) 如果'echo'参数为true,则无返回;如果'echo'为false,返回要输出的菜单。如果没有项目或未找到菜单,则为False。


说明

用法

wp_nav_menu( $args );

给定theme_location参数,该函数显示分配给该位置的菜单。如果不存在此类位置或没有为其分配菜单,参数fallback_cb将确定显示的内容。

如果未给定theme_location参数,则该函数显示:

  • 匹配menu参数所给定 ID, slug, 或 name 的菜单;
  • 否则,就是第一个非空的菜单;
  • 否则 (如果menu参数给定的菜单为空), 由fallback_cb参数给出的函数输出 (默认是wp_page_menu());
  • 否则,什么也没有

以下类应用于菜单项,即HTML<li>标签,由wp_nav_menu()生成:

所以菜单项

  • .menu-item
    这个类被添加到每个菜单项中。
  • .menu-item-has-children
    这个类被添加到有子项的菜单项中。
  • .menu-item-object-{object}
    这个类被添加到每个菜单项中,其中{object}是一个文章类型或一个分类(taxonomy)。
  • .menu-item-object-category
    该类被添加到对应于一个类别的菜单项中。
  • .menu-item-object-tag
    该类被添加到对应于一个标签的菜单项中。
  • .menu-item-object-page
    该类被添加到对应于静态页面的菜单项中。
  • .menu-item-object-{custom}
    该类被添加到对应于自定义文章类型或自定义分类(taxonomy)的菜单项中。
  • .menu-item-type-{type}
    这个类被添加到每个菜单项中,其中 {type} 是 “post_type” 或 “taxonomy”.
  • .menu-item-type-post_type
    该类被添加到对应于文章类型的菜单项中:即静态页面或自定义文章类型。
  • .menu-item-type-taxonomy
    该类被添加到对应于分类法的菜单项中:即类别(category)、标签(tag)或自定义分类。

当前页的菜单项

  • .current-menu-item
    这个类被添加到对应于当前渲染的页面的菜单项。

当前页的父级菜单项

  • .current-menu-parent
    这个类被添加到对应于当前渲染的页面的分层父级菜单项中。
  • .current-{object}-parent
    该类被添加到对应于当前渲染对象的层次父级菜单项中,其中{object}对应.menu-item-object-{object}的值。
  • .current-{type}-parent
    该类被添加到对应于当前渲染类型的层级父级菜单项,其中{type}对应.menu-item-type-{type}的值。

当前页的祖先菜单项

  • .current-menu-ancestor
    这个类被添加到对应于当前渲染的页面的层次祖先菜单项。
  • .current-{object}-ancestor
    该类被添加到对应于当前渲染对象的层次祖先菜单项中,其中{object}对应.menu-item-object-{object}的值。
  • .current-{type}-ancestor
    该类被添加到对应于当前渲染类型的层级祖先菜单项,其中{type}对应.menu-item-type-{type}的值。

网站首页菜单项

  • .menu-item-home
    这个类被添加到对应于网站首页的菜单项中。

wp_page_menu()的向后兼容

添加以下类以保持与[[Function Reference/wp_page_menu|wp_page_menu()]函数输出的向后兼容性:

  • .page_item
    这个类被添加到对应于静态页面的菜单项中。
  • .page_item_has_children
    这个类被添加到有子页面的菜单项上。
  • .page-item-$ID
    这个类被添加到对应于静态页面的菜单项中,其中$ID是静态页面的ID。
  • .current_page_item
    这个类被添加到对应于当前渲染的静态页面的菜单项。
  • .current_page_parent
    这个类被添加到对应于当前渲染的静态页面的分层父级菜单项中。
  • .current_page_ancestor
    这个类被添加到对应于当前渲染的静态页面的层次祖先菜单项。


源码

查看源码 官方文档


更新日志

版本描述
5.5.0添加了container_aria_label参数
4.7.0添加了item_spacing参数
3.0.0开始引入

使用示例

  • 示例1

    以下是现成的代码片段(不是真正的贡献,更重要的是一个快捷方式):

    wp_nav_menu( array $args = array(
    	'menu'				=> "", // (int|string|WP_Term) Desired menu. Accepts a menu ID, slug, name, or object.
    	'menu_class'		=> "", // (string) CSS class to use for the ul element which forms the menu. Default 'menu'.
    	'menu_id'			=> "", // (string) The ID that is applied to the ul element which forms the menu. Default is the menu slug, incremented.
    	'container'			=> "", // (string) Whether to wrap the ul, and what to wrap it with. Default 'div'.
    	'container_class'	=> "", // (string) Class that is applied to the container. Default 'menu-{menu slug}-container'.
    	'container_id'		=> "", // (string) The ID that is applied to the container.
    	'fallback_cb'		=> "", // (callable|bool) If the menu doesn't exists, a callback function will fire. Default is 'wp_page_menu'. Set to false for no fallback.
    	'before'			=> "", // (string) Text before the link markup.
    	'after'				=> "", // (string) Text after the link markup.
    	'link_before'		=> "", // (string) Text before the link text.
    	'link_after'		=> "", // (string) Text after the link text.
    	'echo'				=> "", // (bool) Whether to echo the menu or return it. Default true.
    	'depth'				=> "", // (int) How many levels of the hierarchy are to be included. 0 means all. Default 0.
    	'walker'			=> "", // (object) Instance of a custom walker class.
    	'theme_location'	=> "", // (string) Theme location to be used. Must be registered with register_nav_menu() in order to be selectable by the user.
    	'items_wrap'		=> "", // (string) How the list items should be wrapped. Default is a ul with an id and class. Uses printf() format with numbered placeholders.
    	'item_spacing'		=> "", // (string) Whether to preserve whitespace within the menu's HTML. Accepts 'preserve' or 'discard'. Default 'preserve'.
    ) );
  • 示例2

    登录用户的不同菜单

    此示例将导致为登录的用户显示一个菜单,为未登录的用户显示另一个菜单。

    wp_nav_menu( array(
    	'theme_location' => is_user_logged_in() ? 'logged-in-menu' : 'logged-out-menu'
    ) );
    
  • 示例3

    删除ul包装

    本例将删除包围列表项的ul。用%3$s替换包围的HTML,只会输出菜单项的列表内容,因为items_wrap是使用sprintf()构建的

    items_wrap之前的默认值:

    <ul id="%1$s" class="%2$s">%3$s</ul>
    

    items_wrap之后:

    %3$s
    

    示例:

    wp_nav_menu( array( 'items_wrap' => '%3$s' ) );
    
  • 示例4

    使用自定义Walker函数

    对于更深层次的条件类,需要使用自定义walker函数(在'walker' => new Your_Walker_Function参数中创建)。

    构建新walker函数的最简单方法是从 /wp includes/nav-menu-template.php 复制和扩展默认类(Walker_Nav_Menu),只需自定义所需内容。

    示例:

    此自定义walker函数将向导航菜单添加几个条件类(即子菜单、偶数/奇数等):

    wp_nav_menu( array(
    	'menu'   => 'Something custom walker',
    	'walker' => new WPDocs_Walker_Nav_Menu()
    ) );
    
    /**
     * Custom walker class.
     */
    class WPDocs_Walker_Nav_Menu extends Walker_Nav_Menu {
    
    	/**
    	 * Starts the list before the elements are added.
    	 *
    	 * Adds classes to the unordered list sub-menus.
    	 *
    	 * @param string $output Passed by reference. Used to append additional content.
    	 * @param int    $depth  Depth of menu item. Used for padding.
    	 * @param array  $args   An array of arguments. @see wp_nav_menu()
    	 */
    	function start_lvl( &$output, $depth = 0, $args = array() ) {
    		// Depth-dependent classes.
    		$indent = ( $depth > 0  ? str_repeat( "\t", $depth ) : '' ); // code indent
    		$display_depth = ( $depth + 1); // because it counts the first submenu as 0
    		$classes = array(
    			'sub-menu',
    			( $display_depth % 2  ? 'menu-odd' : 'menu-even' ),
    			( $display_depth >=2 ? 'sub-sub-menu' : '' ),
    			'menu-depth-' . $display_depth
    		);
    		$class_names = implode( ' ', $classes );
    
    		// Build HTML for output.
    		$output .= "\n" . $indent . '<ul class="' . $class_names . '">' . "\n";
    	}
    
    	/**
    	 * Start the element output.
    	 *
    	 * Adds main/sub-classes to the list items and links.
    	 *
    	 * @param string $output Passed by reference. Used to append additional content.
    	 * @param object $item   Menu item data object.
    	 * @param int    $depth  Depth of menu item. Used for padding.
    	 * @param array  $args   An array of arguments. @see wp_nav_menu()
    	 * @param int    $id     Current item ID.
    	 */
    	function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
    		global $wp_query;
    		$indent = ( $depth > 0 ? str_repeat( "\t", $depth ) : '' ); // code indent
    
    		// Depth-dependent classes.
    		$depth_classes = array(
    			( $depth == 0 ? 'main-menu-item' : 'sub-menu-item' ),
    			( $depth >=2 ? 'sub-sub-menu-item' : '' ),
    			( $depth % 2 ? 'menu-item-odd' : 'menu-item-even' ),
    			'menu-item-depth-' . $depth
    		);
    		$depth_class_names = esc_attr( implode( ' ', $depth_classes ) );
    
    		// Passed classes.
    		$classes = empty( $item->classes ) ? array() : (array) $item->classes;
    		$class_names = esc_attr( implode( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) ) );
    
    		// Build HTML.
    		$output .= $indent . '<li id="nav-menu-item-'. $item->ID . '" class="' . $depth_class_names . ' ' . $class_names . '">';
    
    		// Link attributes.
    		$attributes  = ! empty( $item->attr_title ) ? ' title="'  . esc_attr( $item->attr_title ) .'"' : '';
    		$attributes .= ! empty( $item->target )     ? ' target="' . esc_attr( $item->target     ) .'"' : '';
    		$attributes .= ! empty( $item->xfn )        ? ' rel="'    . esc_attr( $item->xfn        ) .'"' : '';
    		$attributes .= ! empty( $item->url )        ? ' href="'   . esc_attr( $item->url        ) .'"' : '';
    		$attributes .= ' class="menu-link ' . ( $depth > 0 ? 'sub-menu-link' : 'main-menu-link' ) . '"';
    
    		// Build HTML output and pass through the proper filter.
    		$item_output = sprintf( '%1$s<a%2$s>%3$s%4$s%5$s</a>%6$s',
    			$args->before,
    			$attributes,
    			$args->link_before,
    			apply_filters( 'the_title', $item->title, $item->ID ),
    			$args->link_after,
    			$args->after
    		);
    		$output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
    	}
    }
    
  • 示例5

    澄清link_beforebefore以及link_afterafter

    link_before/link_after值在链接内输出
    而,before/after值在链接外部输出,但在列表项内。

    例如:
    {before}<a>{link_before}Link Text{link_after}</a>{after}

  • 示例6

    默认示例

    显示第一个非空菜单或wp_page_menu()

    <?php wp_nav_menu(); ?>
    
  • 示例7

    以特定菜单为目标,无需回退到wp_page_menu()

    在没有找到菜单匹配菜单的情况下,传递伪theme_location似乎是防止返回到第一个非空菜单的唯一方法:

    wp_nav_menu( array(
    	'menu'           => 'Project Nav', // Do not fall back to first non-empty menu.
    	'theme_location' => '__no_such_location',
    	'fallback_cb'    => false // Do not fall back to wp_page_menu()
    ) );
    
  • 示例8

    以特定菜单为目标

    wp_nav_menu( array(
    	'menu' => 'Project Nav'
    ) );
    
  • 示例9

    如果没有设置菜单,如何显示占位符菜单

    学分:Salcode.

    如果您刚刚安装了WordPress并激活了一个主题,那么外观中可能还没有“菜单”菜单项。在这些情况下,您可能需要显示自己的占位符菜单,直到该菜单设置完毕。

    为此,请使用fallback回调函数。像这样:

    wp_nav_menu( array( 'fallback_cb' => 'custom_primary_menu_fallback', 'menu' => 'menu', 'container' => false, 'menu_id' => 'menu', 'menu_class'=>'', 'theme_location'=>'primary-menu' ) );
    
    function custom_primary_menu_fallback() {
      ?>
      <ul id="menu"><li><a href="/">Home</a></li><li><a href="/wp-admin/nav-menus.php">Set primary menu</a></li></ul>
      <?php
    }
    
  • 示例10

    如何将.active类添加到活动菜单项

    代码如下:

    add_filter('nav_menu_css_class' , 'special_nav_class' , 10 , 2);
    function special_nav_class($classes, $item){
         if( in_array('current-menu-item', $classes) ){
                 $classes[] = 'active ';
         }
         return $classes;
    }
  • 示例11

    默认情况下,菜单用div容器封装。此页面上的选项将此参数显示为字符串,以更改用于包含菜单的元素。

    然而,这里没有注意到,如果将false作为值传递,则容器将完全移除,只留下ul菜单元素。

    wp_nav_menu(array(
        'container' => false // Removes the container, leaving just the ul element
    ));
    
  • 示例12

    并没有提到容器参数在默认情况下只接受“div”、“nav”和falsy值(“,false,null)。如果要扩展接受的标记参数并在其他内容中包装菜单父ul标记,则必须使用wp_nav_menu_container_allowedtags过滤器并将所需的标记添加到数组中。然而,在大多数情况下,默认的两个标记是最符合逻辑的。

  • 示例13

    如何为菜单项添加父类

    如果菜单项有子菜单,有时可能需要将类添加到菜单项中。

    /**
     * Add a parent CSS class for nav menu items.
     *
     * @param array  $items The menu items, sorted by each menu item's menu order.
     * @return array (maybe) modified parent CSS class.
     */
    function wpdocs_add_menu_parent_class( $items ) {
    	$parents = array();
    
    	// Collect menu items with parents.
    	foreach ( $items as $item ) {
    		if ( $item->menu_item_parent && $item->menu_item_parent > 0 ) {
    			$parents[] = $item->menu_item_parent;
    		}
    	}
    
    	// Add class.
    	foreach ( $items as $item ) {
    		if ( in_array( $item->ID, $parents ) ) {
    			$item->classes[] = 'menu-parent-item';
    		}
    	}
    	return $items;
    }
    add_filter( 'wp_nav_menu_objects', 'wpdocs_add_menu_parent_class' );
    
  • 示例14

    用于显示菜单的简单短码
    这将允许您在添加短码的位置显示菜单,有很大的空间来扩展$args,但保持简单。

    function get_menu($args){
        $menu = isset($atts['menu']) ? $atts['menu'] : '';
        ob_start();
        wp_nav_menu(array(
            'menu' => $menu
        ) );
        return ob_get_clean();
    }
    add_shortcode('get_menu', 'get_menu');

    使用示例:

    [get_menu menu="Main Menu"]

  • 示例15

    您可以简单地筛选菜单项类名,而不是大型Walker

    // adds useful menu-item class names
    function your_theme_menu_item_class( $classes, $item ) {
    
      // Add slugs to menu-items
      if ( 'category' == $item->object ) {
        $category = get_category( $item->object_id );
        $classes[] = 'category-' . $category->slug;
      } elseif ( 'format' == $item->object ){
        $format = get_term($item->object_id);
        $classes[] = 'format-' . $format->slug;
      }
      return $classes;  
    }
    
    add_filter( 'nav_menu_css_class', 'your_theme_menu_item_class', 10, 2);
    
  • 示例16

    向菜单项添加条件类

    此示例允许您根据指定的条件向菜单项添加自定义类。别忘了改变条件。

    /**
     * Filter the CSS class for a nav menu based on a condition.
     *
     * @param array  $classes The CSS classes that are applied to the menu item's <li> element.
     * @param object $item    The current menu item.
     * @return array (maybe) modified nav menu class.
     */
    function wpdocs_special_nav_class( $classes, $item ) {
    	if ( is_single() && 'Blog' == $item->title ) {
    		// Notice you can change the conditional from is_single() and $item->title
    		$classes[] = "special-class";
    	}
    	return $classes;
    }
    add_filter( 'nav_menu_css_class' , 'wpdocs_special_nav_class' , 10, 2 );
    
  • 示例17

    删除默认div容器

    为了移除封装菜单的默认div容器,只需:

    在数组中使用'container'参数
    并让它空着

    如以下示例所示:

    wp_nav_menu(array(
        'container' => '', // Leaving it empty removes the <div> container.
    ));
  • 示例18

    默认情况下,container参数的唯一可接受值是divnav,因此任何其他值都会导致它不显示。

  • 示例19

    我发现echo参数非常有用。

    // 1) store the menu in a var:
    $my_wp_nav_menu = wp_nav_menu(
    	array(
    		'echo' => false
    	)
    );
    
    // 2) do whatever you want with the menu array before displaying it:
    //    (just an) example: remove slashes from menu voices:
    $my_wp_nav_menu = str_replace( array( '%5C', '\' ) ), '', $my_wp_nav_menu );
    
    echo $my_wp_nav_menu;
  • 示例20

    菜单slug

    菜单slug构造为:[menu name]-menu

    例如,对于名为“main”的菜单,slug将是“main-menu

    你们可以在terms数据库表中找到菜单slug。

  • 示例21

    在菜单开头添加一个单词

    此示例允许您将所选单词作为列表项添加到菜单的开头。在本例中,文字“Menu:”添加在开头。您可能希望在列表项上设置一个id(本例中为“item-id”),以便可以使用CSS对其进行样式设置。

    wp_nav_menu( array(
    	'theme_location' => 'primary',
    	'items_wrap'     => '<ul><li id="item-id"><?php __( 'Menu:', 'textdomain' ); ?></li>%3$s</ul>'
    ) );
    
  • 示例22

    制作一个短代码以在编辑器中显示菜单

    // Function that will return our Wordpress menu
    function show_wp_menu_function($atts, $content = null) {
    	
    	extract(shortcode_atts(array(  
    		'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'      => '',
    		'depth'           => 0,
    		'walker'          => '',
    		'theme_location'  => ''), 
    		$atts));
     
     
    	return wp_nav_menu( array( 
    		'menu'            => $menu, 
    		'container'       => $container, 
    		'container_class' => $container_class, 
    		'container_id'    => $container_id, 
    		'menu_class'      => $menu_class, 
    		'menu_id'         => $menu_id,
    		'echo'            => false,
    		'fallback_cb'     => $fallback_cb,
    		'before'          => $before,
    		'after'           => $after,
    		'link_before'     => $link_before,
    		'link_after'      => $link_after,
    		'depth'           => $depth,
    		'walker'          => $walker,
    		'theme_location'  => $theme_location));
    }
    //Create the shortcode
    add_shortcode("show_wp_menu", "show_wp_menu_function");

    简单使用:
    [show_wp_menu menu="wp_menu_name_here" menu_class="my_menu_class"]