I've looked around everywhere but I can't seem to find an answer to this specific case. I am attempting to output the parent description and featured image of the page right after the sub-menu begins. I have the follow code which works, but iterates over every link, which is messy. I was able to at least modify the depth so it only outputs the content once, but I'd like to a) clean it up and b) find the actual correct way to do this. Here is my current walker:
class Description_Walker extends Walker_Nav_Menu {
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
)
);
! empty ( $class_names )
and $class_names = ' class="'. esc_attr( $class_names ) . '"';
// Build default menu items
$output .= "<li id='menu-item-$item->ID' $class_names>";
$attributes = '';
! empty( $item->attr_title )
and $attributes .= ' title="' . esc_attr( $item->attr_title ) .'"';
! empty( $item->target )
and $attributes .= ' target="' . esc_attr( $item->target ) .'"';
! empty( $item->xfn )
and $attributes .= ' rel="' . esc_attr( $item->xfn ) .'"';
! empty( $item->url )
and $attributes .= ' href="' . esc_attr( $item->url ) .'"';
// get thumbnail
$thumbnail = '';
if ( has_post_thumbnail( $item->object_id ) and 0 == $depth ) {
$thumbnail = get_the_post_thumbnail( $item->object_id );
}
// Build the description (you may need to change the depth to 0, 1, or 2)
$description = ( ! empty ( $item->description ) and 2 == $depth )
? '<span class="nav_desc">'. $item->description . '</span>' : '';
$title = apply_filters( 'the_title', $item->title, $item->ID );
$item_output .= $args->before;
$item_output .= '<a'. $attributes .'>';
$item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
$item_output .= '</a>';
// Only apply to the top level links, do not iterate over any sub-menu items:
if ( 0 == $depth ) {
$item_output .= "\n$indent<div class=\"dropdown\"><div class=\"container\"><div class=\"thumbnail\">".$thumbnail."</div><div class=\"nav-info\">" . $item->description . "</div>\n";
}
$item_output .= $args->after;
// Since $output is called by reference we don't need to return anything.
$output .= apply_filters(
'walker_nav_menu_start_el', $item_output, $item, $depth,$args);
}
function end_lvl(&$output, $depth) {
$indent = str_repeat("\t", $depth);
$output .= "\n$indent</ul></div>";
}
}
EDIT:
I was able to figure this out, answer below. Correct code above. It's not the ideal situation, I really just wanted to output the content right after the LI, but in the end I actually needed the extra markup that I was injecting for the styling I need to do later.
I welcome any critiques on this since I still feel it's messy, but dag nabbit, it works!