I am working on a custom menu system using the Walker_Nav_Menu
function. I have nearly got it working but i cant get through a few barriers which i hope someone can assist on.
What am i trying to achieve?:
<nav id="menu">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about-us">About Us</a></li>
<li>
<span>Second Layer</span>
<div>
<ul>
<li><a href="/second-layer/second-layer/">Second Layer</a></li>
<li><a href="/second-layer/blah-blah/">blah blah</a></li>
</ul>
</div>
</li>
</ul>
</nav>
What is it currently doing?:
<nav id="menu">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about-us">About Us</a></li>
<li><a href="/second-layer/second-layer/">Second Layer</a>
<span></span>
<div>
<ul>
<li><a href="/second-layer/blah-blah/">blah blah</a></li>
</ul>
</div>
</li>
</ul>
</nav>
I am trying to get the menu so if menu item has child items, it places it within a span and add that menu item as the first item under.
Here is what i have done with the Walker_nav_menu
class Excerpt_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>';
$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 ) .'"' : '';
if($depth == 0)
{
$item_output = $args->before;
$item_output .= '<a'. $attributes .'>';
$item_output .= $args->link_before .apply_filters( 'the_title', $item->title, $item->ID );
$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 );
}else if($depth == 1){
$item_output .= $args->before;
$item_output .= '<a'. $attributes .'>';
$item_output .= $args->link_before .apply_filters( 'the_title', $item->title, $item->ID );
$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 );
}
}
function start_lvl(&$output, $depth) {
$indent = str_repeat("t", $depth);
$output .= "n$indent" . $item_output = "<span>" . $args->link_before .apply_filters( 'the_title', $item->title, $item->ID ) . "</span>" . "<div><ul>n";
}
}
Try this code. you’ll notice I have the span tag wrapped around the menu description copy. Feel free to remove that call and put whatever you need in there.
in you header.php file call the new walker menu like
//place in functions.php