2

I am creating a custom nav walker but having trouble outputting parent menu item title in start_lvl function. I want to output it right after the <div class="dropdown"> in the following start_lvl function.

function start_lvl(&$output, $depth = 0, $args = array()) {

        $indent = str_repeat("\t", $depth);

        if ($depth == 0) {

            $out_div = ' <div class="dropdown-wrapper"><div class="dropdown">This is where I want to output parent item title';
        }
        else {
            $out_div = '';
        }
        // build html
        $output.= "\n" . $indent . $out_div . '<ul>' . "\n";
    }

Here is the complete nav walker code.

class my_custom_navwalker extends Walker_Nav_Menu {

    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 = 0, $args = array()) {

        $indent = str_repeat("\t", $depth);

        if ($depth == 0) {

            $out_div = ' <div class="dropdown-wrapper"><div class="dropdown">';
        }
        else {
            $out_div = '';
        }
        // build html
        $output.= "\n" . $indent . $out_div . '<ul>' . "\n";
    }

    function start_el(&$output, $item, $depth = 0, $args = array() , $id = 0) {
        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 ) . '"';

        if ($args->has_children && $depth == 0) {
            $has_sub = ' has-sub';
        }

        $output.= $indent . '<li id="menu-item-' . $item->ID . '"' . $value . 'class="' . $class_names . $has_sub . '">';

        $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 = '';
        $append = '';

        //$description = !empty($item->description) ? '<div class="">' . $item->description . '</div>' : '';
        // 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.= '</a>';
        //$item_output.= $description . $args->link_after;
        $item_output.= $args->after;
        $output.= apply_filters('walker_nav_menu_start_el', $item_output, $item, $depth, $args, $id);
    }

    function end_lvl(&$output, $depth = 0, $args = array())
    {
        $indent = str_repeat("\t", $depth);
        if ($depth == 0) {
            $out_div_close = '</div></div>';
        }
        else {
            $out_div_close = '';
        }
        $output.= "$indent" . "\n";

        $output.= "</ul>" . $out_div_close . "\n";
    }
}

Any help would be highly appreciated.

thanks in advance.

  • 1
    I may not have time to create a solution but maybe you're looking at the wrong function, maybe you should try to add the wrapper on start_el when it's depth is 0 and it has_children. This way you have access to the $item nav menu object. – Howdy_McGee Sep 6 '16 at 21:56
  • I think I tried that but how can that output right before the submenu <ul> ? because that is declared in start_lvl function – bakar Sep 6 '16 at 22:03
0

Finally, after some thorough search and as suggested by @Howdy_McGee in his comment I got the Nav Walker working as expected. For those looking for something similar, here is how I did it.

Instead of outputting parent menu item title in start_lvl function, I included it in start_el function and the final code looked like following:

class my_custom_navwalker extends Walker_Nav_Menu {

    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 = 0, $args = array()) {

        $indent = str_repeat("\t", $depth);

        if ($depth == 0) {

            $out_div = '';
        }
        else {
            $out_div = '';
        }
        // build html
        $output.= "\n" . $indent . $out_div . '<ul>' . "\n";
    }

    function start_el(&$output, $item, $depth = 0, $args = array() , $id = 0) {
        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 ) . '"';

        if ($args->has_children && $depth == 0) {
            $has_sub = ' has-sub';
        }

        $output.= $indent . '<li id="menu-item-' . $item->ID . '"' . $value . 'class="' . $class_names . $has_sub . '">';

        $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 = '';
        $append = '';

        //$description = !empty($item->description) ? '<div class="">' . $item->description . '</div>' : '';
        // 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.= '</a>';
        //$item_output.= $description . $args->link_after;


        if ( $args->has_children && $depth == 0) {

            $item_output .= ' <div class="dropdown-wrapper"><div class="dropdown"><div class="item-title-class">'.$item->title.'</div>';

        }

        $item_output.= $args->after;
        $output.= apply_filters('walker_nav_menu_start_el', $item_output, $item, $depth, $args, $id);
    }

    function end_lvl(&$output, $depth = 0, $args = array())
    {
        $indent = str_repeat("\t", $depth);
        if ($depth == 0) {
            $out_div_close = '';
        }
        else {
            $out_div_close = '';
        }
        $output.= "$indent" . "\n";

        $output.= "</ul>" . $out_div_close . "\n";
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.