参数
- $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()
- 'menu'
返回
(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());
- 否则,什么也没有
菜单项 CSS 类
以下类应用于菜单项,即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 | 开始引入 |
使用示例
以下是现成的代码片段(不是真正的贡献,更重要的是一个快捷方式):
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'. ) );
登录用户的不同菜单
此示例将导致为登录的用户显示一个菜单,为未登录的用户显示另一个菜单。
wp_nav_menu( array( 'theme_location' => is_user_logged_in() ? 'logged-in-menu' : 'logged-out-menu' ) );
删除
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' ) );
使用自定义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 ); } }
澄清
link_before
与before
以及link_after
与after
link_before
/link_after
值在链接内输出
而,before
/after
值在链接外部输出,但在列表项内。例如:
{before}<a>{link_before}Link Text{link_after}</a>{after}
默认示例
显示第一个非空菜单或
wp_page_menu()
。<?php wp_nav_menu(); ?>
以特定菜单为目标,无需回退到
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() ) );
以特定菜单为目标
wp_nav_menu( array( 'menu' => 'Project Nav' ) );
如果没有设置菜单,如何显示占位符菜单
如果您刚刚安装了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 }
如何将
.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; }
默认情况下,菜单用
div
容器封装。此页面上的选项将此参数显示为字符串,以更改用于包含菜单的元素。然而,这里没有注意到,如果将
false
作为值传递,则容器将完全移除,只留下ul
菜单元素。wp_nav_menu(array( 'container' => false // Removes the container, leaving just the ul element ));
并没有提到容器参数在默认情况下只接受“div”、“nav”和falsy值(“,false,null)。如果要扩展接受的标记参数并在其他内容中包装菜单父ul标记,则必须使用wp_nav_menu_container_allowedtags过滤器并将所需的标记添加到数组中。然而,在大多数情况下,默认的两个标记是最符合逻辑的。
如何为菜单项添加父类
如果菜单项有子菜单,有时可能需要将类添加到菜单项中。
/** * 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' );
用于显示菜单的简单短码
这将允许您在添加短码的位置显示菜单,有很大的空间来扩展$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"]
您可以简单地筛选菜单项类名,而不是大型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);
向菜单项添加条件类
此示例允许您根据指定的条件向菜单项添加自定义类。别忘了改变条件。
/** * 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 );
删除默认div容器
为了移除封装菜单的默认
div
容器,只需:在数组中使用'container'参数
并让它空着如以下示例所示:
wp_nav_menu(array( 'container' => '', // Leaving it empty removes the <div> container. ));
默认情况下,
container
参数的唯一可接受值是div
和nav
,因此任何其他值都会导致它不显示。我发现
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;
菜单slug
菜单slug构造为:
[menu name]-menu
例如,对于名为“main”的菜单,slug将是“
main-menu
”你们可以在terms数据库表中找到菜单slug。
在菜单开头添加一个单词
此示例允许您将所选单词作为列表项添加到菜单的开头。在本例中,文字“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>' ) );
制作一个短代码以在编辑器中显示菜单
// 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"]