• Resolved ADvi

    (@advi)


    Hi. I have this to codes for menu
    1.

    class MY_Walker_Nav_Menu extends Walker_Nav_Menu
    {
        public function start_el(&$output, $item, $depth = 0, $args = array(), $id = 0) {
            $class_names = join( ' ', $item->classes );
            $class_names = ' class="' . esc_attr( $class_names ). '"';
            $output.= '<li id="menu-item-' . $item->ID . '"' . $class_names . '>';
            $attributes = '';
    
            $attributes.= !empty( $item->url ) ? ' href="' . esc_attr( $item->url ) . '"' : '';
            $item_output = $args->before;
    
            if($args->walker->has_children)
            {
                $item_output.= '<div class="header__menu-top"><a' . $attributes . '>' . $item->title.'</a>';
            }
            else
            {
                $item_output.= '<a'. $attributes . '>' . $item->title . '</a>';
            };
    
            $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
        }
    
        public function start_lvl( &$output, $depth = 0, $args = array() )
        {
            $indent = str_repeat("\t", $depth);
            $output .= "\n$indent<button class='header__menu-toggle-children'></button></div><ul class='sub-menu'>\n";
        }
    
        public function end_lvl( &$output, $depth = 0, $args = array() )
        {
            $indent = str_repeat("\t", $depth);
            $output .= "$indent</ul>\n";
        }
    }

    and the second

    2.

    function my_nav_description( $item_output, $item, $depth, $args )
    {
        if ( 'primary' == $args->theme_location && $item->description )
        {
            $item_output = str_replace( $args->link_after . '</a>', '<div class="menu-item-description">' . $item->description . '</div>' . $args->link_after . '</a>', $item_output );
        }
    
        return $item_output;
    }
    add_filter( 'walker_nav_menu_start_el', 'my_nav_description', 10, 4 );

    So, the question is HOW can I combine them into one code? Is it possible?

    And one more – how can I add <button class='header__menu-toggle-children2'></button> only for submenus? Now <button class='header__menu-toggle-children'></button> button appears for first level menus and for all submenus.

    I need class header__menu-toggle-children2 for submenu’s buttons and header__menu-toggle-children for first level.

    Result I want to achieve https://pastebin.com/vaeAjpRw

    Thanks.

    • This topic was modified 6 years, 4 months ago by ADvi.
Viewing 4 replies - 1 through 4 (of 4 total)
  • Moderator bcworkz

    (@bcworkz)

    If you are using a custom walker, there is no need to hook ‘walker_nav_menu_start_el’ filter. Just do whatever it is within your method override. Is this what you are asking how to do?

    Just add the filter callback’s if conditional to your method override just before the filter application. Adjust the variable names to conform with the method, for instance $item_output will become $output.

    To set specific classes by level, use the $depth argument. Something like

    $level = (0 != $depth ? '2' : '');
    $output .= "\n$indent<button class='header__menu-toggle-children{$level}'></button></div><ul class='sub-menu'>\n";
    Thread Starter ADvi

    (@advi)

    I’ve changed my code to combine first and second. I did everything right?

    class my_Walker_Nav_Menu extends Walker_Nav_Menu
    {
        public function start_el(&$output, $item, $depth = 0, $args = array(), $id = 0) {
            // назначаем классы li-элементу и выводим его
            $class_names = join( ' ', $item->classes );
            $class_names = ' class="' . esc_attr( $class_names ). '"';
            $output.= '<li id="menu-item-' . $item->ID . '"' . $class_names . '>';
            $attributes = '';
    
            // назначаем атрибуты a-элементу
            $attributes.= !empty( $item->url ) ? ' href="' . esc_attr( $item->url ) . '"' : '';
            $item_output = $args->before;
    
            if($args->walker->has_children)
            {
                $item_output.= '<div class="header__menu-top"><a' . $attributes . '>' . $item->title.'</a>';
            }
            else
            {
                $item_output.= '<a'. $attributes . '>' . $item->title . '</a>';
            };
    
            if ( 'primary' == $args->theme_location && $item->description )
            {
                $item_output = str_replace( $args->link_after . '</a>', '<div class="menu-item-description">' . $item->description . '</div>' . $args->link_after . '</a>', $item_output );
            }
    
            $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
        }
    
        public function start_lvl( &$output, $depth = 0, $args = array() )
        {
            $indent = str_repeat("\t", $depth);
            $output .= "\n$indent<button class='header__menu-toggle-children'></button></div><ul class='sub-menu'>\n";
        }
    
        public function end_lvl( &$output, $depth = 0, $args = array() )
        {
            $indent = str_repeat("\t", $depth);
            $output .= "$indent</ul>\n";
        }
    }

    And I can’t understand how to add <button class='header__menu-toggle-children'></button> only for first level menu and <button class='header__menu-toggle-children2'></button> for all submenus? Could you please help to integrate this condition to my code above?
    Thanks for help!

    Moderator bcworkz

    (@bcworkz)

    Yes, your latest start_el() method version is what I had in mind.

    You want to alter the button class based on level in the start_lvl() method, correct? This should do it:

    public function start_lvl( &$output, $depth = 0, $args = array() )
        {
            $indent = str_repeat("\t", $depth);
            $level = (0 != $depth ? '2' : '');
            $output .= "\n$indent<button class=\"header__menu-toggle-children{$level}\"></button></div><ul class=\"sub-menu\">\n";
        }

    I took the liberty to alter button attribute quotes to be double instead of single. The element attributes are double quoted already. Even though browsers don’t care, inconsistent quoting sort of bothers me ?? If you really wanted singles, replace each occurrence of \" with '.

    Thread Starter ADvi

    (@advi)

    Thanks! It works as expected!

Viewing 4 replies - 1 through 4 (of 4 total)
  • The topic ‘Customize menu’ is closed to new replies.