> WordPress中文手册 > wordpress进阶教程(二十三):给菜单标签中添加自定义类属性

在制作WordPress主题实际应用中,在做一些菜单特效的时候,我们经常需要在输出的菜单中添加自定义的类,比如我们需要一个下面类似的菜单结构(在一级菜单的<li>标签中添加level1的类,在二级菜单的<li>标签中中添加level2的类,然后在含有子级菜单的菜单<li>标签中添加类haschildren):

<ul> <li class="level1"><a href="http://dba.cn">阿树工作室一级菜单</a></li> <li class="haschildren level1"><a href="http://dba.cn">阿树工作室一级菜单(有下拉)</a> <ul class="sub-menu"> <li class="level2"><a href="http://dba.cn">阿树工作室二级菜单</a></li> </ul> </li> </ul> <!--上面的代码省略了wp默认输出的class类和id--> <?PHP $defaults = array( 'theme_location' => '', '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' => '', 'items_wrap' => '<ul id="%1$s" class="%2$s">%3$s</ul>', 'depth' => 0, 'walker' => '' //该参数为类,可用来改变菜单的输出 ,默认为 Walker_Nav_Menu ); wp_nav_menu( $defaults ); ?> /*******ashu_menu_walker继承类Walker_Nav_Menu***********/ class ashu_menu_walker extends Walker_Nav_Menu{ function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output ) { $id_field = $this->db_fields['id']; if( isset($children_elements[$element->$id_field]) ) { $classes = empty( $element->classes ) ? array() : (array) $element->classes; $classes[] = 'haschildren'; $element->classes =$classes; } if( 0 == $depth ){ $classes = empty( $element->classes ) ? array() : (array) $element->classes; $classes[] = 'level1'; $element->classes =$classes; } if( 1 == $depth ){ $classes = empty( $element->classes ) ? array() : (array) $element->classes; $classes[] = 'level2'; $element->classes =$classes; } if( 2 == $depth ){ $classes = empty( $element->classes ) ? array() : (array) $element->classes; $classes[] = 'level3'; $element->classes =$classes; } return parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output ); } } <?php $args = array( 'walker' => new ashu_menu_walker(), //注意是 new ashu_menu_walker(); 'theme_location' => 'ashu-menu', ); wp_nav_menu($args); ?>

wordperss使用wp_nav_menu函数输出菜单是不会有这个效果的,但是wp_nav_menu函数有个重要的参数:

<ul> <li class="level1"><a href="http://dba.cn">阿树工作室一级菜单</a></li> <li class="haschildren level1"><a href="http://dba.cn">阿树工作室一级菜单(有下拉)</a> <ul class="sub-menu"> <li class="level2"><a href="http://dba.cn">阿树工作室二级菜单</a></li> </ul> </li> </ul> <!--上面的代码省略了wp默认输出的class类和id--> <?php $defaults = array( 'theme_location' => '', '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' => '', 'items_wrap' => '<ul id="%1$s" class="%2$s">%3$s</ul>', 'depth' => 0, 'walker' => '' //该参数为类,可用来改变菜单的输出 ,默认为 Walker_Nav_Menu ); wp_nav_menu( $defaults ); ?> /*******ashu_menu_walker继承类Walker_Nav_Menu***********/ class ashu_menu_walker extends Walker_Nav_Menu{ function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output ) { $id_field = $this->db_fields['id']; if( isset($children_elements[$element->$id_field]) ) { $classes = empty( $element->classes ) ? array() : (array) $element->classes; $classes[] = 'haschildren'; $element->classes =$classes; } if( 0 == $depth ){ $classes = empty( $element->classes ) ? array() : (array) $element->classes; $classes[] = 'level1'; $element->classes =$classes; } if( 1 == $depth ){ $classes = empty( $element->classes ) ? array() : (array) $element->classes; $classes[] = 'level2'; $element->classes =$classes; } if( 2 == $depth ){ $classes = empty( $element->classes ) ? array() : (array) $element->classes; $classes[] = 'level3'; $element->classes =$classes; } return parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output ); } } <?php $args = array( 'walker' => new ashu_menu_walker(), //注意是 new ashu_menu_walker(); 'theme_location' => 'ashu-menu', ); wp_nav_menu($args); ?>

要实现我们要的效果,第一步我们要为输出菜单中的walker参数准备一个类(将下面的代码加入到主题的functions.php中):

<ul> <li class="level1"><a href="http://dba.cn">阿树工作室一级菜单</a></li> <li class="haschildren level1"><a href="http://dba.cn">阿树工作室一级菜单(有下拉)</a> <ul class="sub-menu"> <li class="level2"><a href="http://dba.cn">阿树工作室二级菜单</a></li> </ul> </li> </ul> <!--上面的代码省略了wp默认输出的class类和id--> <?php $defaults = array( 'theme_location' => '', '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' => '', 'items_wrap' => '<ul id="%1$s" class="%2$s">%3$s</ul>', 'depth' => 0, 'walker' => '' //该参数为类,可用来改变菜单的输出 ,默认为 Walker_Nav_Menu ); wp_nav_menu( $defaults ); ?> /*******ashu_menu_walker继承类Walker_Nav_Menu***********/ class ashu_menu_walker extends Walker_Nav_Menu{ function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output ) { $id_field = $this->db_fields['id']; if( isset($children_elements[$element->$id_field]) ) { $classes = empty( $element->classes ) ? array() : (array) $element->classes; $classes[] = 'haschildren'; $element->classes =$classes; } if( 0 == $depth ){ $classes = empty( $element->classes ) ? array() : (array) $element->classes; $classes[] = 'level1'; $element->classes =$classes; } if( 1 == $depth ){ $classes = empty( $element->classes ) ? array() : (array) $element->classes; $classes[] = 'level2'; $element->classes =$classes; } if( 2 == $depth ){ $classes = empty( $element->classes ) ? array() : (array) $element->classes; $classes[] = 'level3'; $element->classes =$classes; } return parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output ); } } <?php $args = array( 'walker' => new ashu_menu_walker(), //注意是 new ashu_menu_walker(); 'theme_location' => 'ashu-menu', ); wp_nav_menu($args); ?>

第二步骤,前台调用的时候设置walker参数为我们刚刚添加的类,示例:

<ul> <li class="level1"><a href="http://dba.cn">阿树工作室一级菜单</a></li> <li class="haschildren level1"><a href="http://dba.cn">阿树工作室一级菜单(有下拉)</a> <ul class="sub-menu"> <li class="level2"><a href="http://dba.cn">阿树工作室二级菜单</a></li> </ul> </li> </ul> <!--上面的代码省略了wp默认输出的class类和id--> <?php $defaults = array( 'theme_location' => '', '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' => '', 'items_wrap' => '<ul id="%1$s" class="%2$s">%3$s</ul>', 'depth' => 0, 'walker' => '' //该参数为类,可用来改变菜单的输出 ,默认为 Walker_Nav_Menu ); wp_nav_menu( $defaults ); ?> /*******ashu_menu_walker继承类Walker_Nav_Menu***********/ class ashu_menu_walker extends Walker_Nav_Menu{ function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output ) { $id_field = $this->db_fields['id']; if( isset($children_elements[$element->$id_field]) ) { $classes = empty( $element->classes ) ? array() : (array) $element->classes; $classes[] = 'haschildren'; $element->classes =$classes; } if( 0 == $depth ){ $classes = empty( $element->classes ) ? array() : (array) $element->classes; $classes[] = 'level1'; $element->classes =$classes; } if( 1 == $depth ){ $classes = empty( $element->classes ) ? array() : (array) $element->classes; $classes[] = 'level2'; $element->classes =$classes; } if( 2 == $depth ){ $classes = empty( $element->classes ) ? array() : (array) $element->classes; $classes[] = 'level3'; $element->classes =$classes; } return parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output ); } } <?php $args = array( 'walker' => new ashu_menu_walker(), //注意是 new ashu_menu_walker(); 'theme_location' => 'ashu-menu', ); wp_nav_menu($args); ?>

这样输出菜单即为我们前面需要的效果。