wordpress - WP Menu walker function to display parent description and wrap parent in own div -
anyone know how write custom walker function wp_nav_menu will...
1) display item description parent items only.
2) wrap parent item (title, link , description) in it's own div only if has children.
(i've simplified div's , ul's have no classes)
<div> <ul> <!-- parent children --> <li class="has_children"> <div class="first-level"> <a>parent item</a> <span class="desc">description</span> </div> <ul class="sub-menu level-0"> <li class="odd"><a>child item</a></li> <li class="even no has_children"><a>child item</a> <ul class="sub-menu level-1"> <li class="odd"><a>child item</a></li> </ul> </li> <li class="odd"><a>child item</a></li> <li class="even"><a>child item</a></li> <li class="odd"><a>child item</a></li> </ul> </li> <!-- parent without children --> <li> <div class="first-level"> <a>parent item</a> <span class="desc">description</span> </div> </li> </ul> </div>
^^ of above classes , id's should in addition in wp_nav_menu
this based on this question , this question
class description_walker extends walker_nav_menu { /** * start element output. * * @param string $output passed reference. used append additional content. * @param object $item menu item data object. * @param int $depth depth of menu item. may used padding. * @param array $args additional strings. * @return void */ function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output ) { $id_field = $this->db_fields['id']; if ( is_object( $args[0] ) ) { $args[0]->has_children = ! empty( $children_elements[$element->$id_field] ); } return parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output ); } function start_lvl( &$output, $depth ) { // depth dependent classes $indent = ( $depth > 0 ? str_repeat( "\t", $depth ) : '' ); // code indent $display_depth = ( $depth); // because counts first submenu 0 $classes = array('sub-menu','level-' . $display_depth); $class_names = implode( ' ', $classes ); // build html $output .= "\n" . $indent . '<ul class="' . $class_names . '">' . "\n"; } function start_el(&$output, $item, $depth, $args) { $classes = empty ( $item->classes ) ? array () : (array) $item->classes; $class_names = join( ' ' , apply_filters( 'nav_menu_css_class' , array_filter( $classes ), $item ) ); if ($args->has_children && $depth == 0){ ! empty ( $class_names ) , $class_names = ' class="'. esc_attr( $class_names ) . ' has_children"'; }else{ ! empty ( $class_names ) , $class_names = ' class="'. esc_attr( $class_names ) . '"'; } $output .= "<li id='menu-item-$item->id' $class_names>" ; $attributes = ''; ! empty( $item->attr_title ) , $attributes .= ' title="' . esc_attr( $item->attr_title ) .'"'; ! empty( $item->target ) , $attributes .= ' target="' . esc_attr( $item->target ) .'"'; ! empty( $item->xfn ) , $attributes .= ' rel="' . esc_attr( $item->xfn ) .'"'; ! empty( $item->url ) , $attributes .= ' href="' . esc_attr( $item->url ) .'"'; // insert description top level elements // may change $description = ( ! empty ( $item->description ) , 0 == $depth ) ? '<span class="desc">' . esc_attr( $item->description ) . '</span>' : ''; $title = apply_filters( 'the_title', $item->title, $item->id ); if ( $depth == 0 ) {//top level items $item_output = $args->before ."<div class='first-level'>" . "<a $attributes>" . $args->link_before . $title . '</a>' . $args->link_after . $description . '</div>' . $args->after; }else{//everything else $item_output = $args->before . "<a $attributes>" . $args->link_before . $title . '</a> ' . $args->link_after . $args->after; } // since $output called reference don't need return anything. $output .= apply_filters( 'walker_nav_menu_start_el' , $item_output , $item , $depth , $args ); } }
and call walker
<?php wp_nav_menu( array('walker' => new description_walker )); ?>
Comments
Post a Comment