为 WordPress 3.0 自定义菜单添加描述

WordPress 3.0 增加了一个强大的自定义菜单功能,但美中不足是要实现题图这样包含描述的菜单时,单靠目前 WordPress 的功能还无法实现。本文将教你改变 WordPress 默认的菜单输出,打造更加个性的菜单。
也许你已经知道,当后台出现 Appearance > Menus 这个菜单项的时候,就标明你使用的主题支持 WordPress 3.0 自定义菜单。只需要用 wp_nav_menu() 函数进行调用即可。但问题是 WordPress 输出的菜单 HTML 结构如下:
1 2 3 4 5 6 | <ul id="menu-main">
<li><a href="#">Home</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Contact</a></li>
<li><a href="#">Blog</a></li>
</ul> |
但我们需要的是像下面这种结构的菜单:
1 2 3 4 5 6 | <ul id="menu-main">
<li><a href="#"><strong>Home</strong><span>Description</span></a></li>
<li><a href="#"><strong>About</strong><span>Description</span></a></li>
<li><a href="#"><strong>Contact</strong><span>Description</span></a></li>
<li><a href="#"><strong>Blog</strong><span>Description</span></a></li>
</ul> |
通过对比,很明显 WordPress 默认输出的菜单结构并不能满足我们的要求。我们需要做的是先为每个菜单项写上 description,然后添加一个 filter 对 WordPress 输出的菜单进行整理。
在 Appearance > Menus 页面,菜单项的 description 输入框默认是隐藏的,我们可以在页顶的 Screen Options 里把 Description 勾上。

然后我们就开始为菜单项加上描述吧!

在默认情况下,WordPress 已经自动为 Page 菜单项写上了长长的描述,在这里我们可以把这些描述改为自己喜欢的内容。
接下来我们要写一个 filter 用来整理 WordPress 输出的菜单代码。wp_nav_menu() 函数有一个 walker 参数,我们通过这个参数来调用 filter。下面是 filter 的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | class description_walker extends Walker_Nav_Menu { function start_el(&$output, $item, $depth, $args) { global $wp_query; $indent = ( $depth ) ? str_repeat( "\t", $depth ) : ''; $class_names = $value = ''; $classes = empty( $item->classes ) ? array() : (array) $item->classes; $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) ); $class_names = ' class="'. esc_attr( $class_names ) . '"'; $output .= $indent . '<li id="menu-item-'. $item->ID . '"' . $value . $class_names .'>'; $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 ) .'"' : ''; $prepend = '<strong>'; $append = '</strong>'; $description = ! empty( $item->description ) ? '<span>'.esc_attr( $item->description ).'</span>' : ''; if($depth != 0) { $description = $append = $prepend = ""; } $item_output = $args->before; $item_output .= '<a '. $attributes .'>'; $item_output .= $args->link_before .$prepend.apply_filters( 'the_title', $item->title, $item->ID ).$append; $item_output .= $description.$args->link_after; $item_output .= '</a>'; $item_output .= $args->after; $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args ); } } </li> |
这个 filter 只是在 WordPress 默认的 walker 脚本的基础上修改了一些内容(原代码在 wp-includes/nav-menu-template.php),并且只为顶级菜单项添加描述。
最后一步,我们只需在调用菜单的时候告诉 WordPress:“调用这个菜单的时候使用我自己的 walker 脚本”,WordPress 就会自动生成你所需要的结构的菜单了。在调用菜单是,我们这样写:
1 2 3 4 5 6 7 8 9 10 11 | wp_nav_menu( array( 'container' =>false, 'menu_class' => 'nav', 'echo' => true, 'before' => '', 'after' => '', 'link_before' => '', 'link_after' => '', 'depth' => 0, 'walker' => new description_walker()) ); |
要令菜单更好看的话,我们只需要编写自己喜欢的 CSS 样式即可。






还没有用过此项
当时升级到3.0就直接还原备份了,感觉这次的版本有点儿杯具 ~
这个正是我需要的,在升级之前学习一下
我即将换的主题就集成了这个功能,dropdown也很好的支持。
这下写菜单就安逸多了
—.—!!!!看到代码就晕乎乎了…..囧
@小邪
3.0版其实是不错的,只是对单用户博客来说有点多余的功能加入了
@万戈
我都没升级
@hzlzh
这个实现起来很简单
还没有升级,先学习吧。
好累,想睡觉
如何在自定义菜单中插图标?
@funnyboy
指定菜单项的class name后通过CSS修改样式就可以了