Ответы пользователя по тегу PHP
  • Как добавить класс на последний ul.sub-menu в Walker_Nav_Menu?

    ElizavetaKrasova
    @ElizavetaKrasova Автор вопроса
    На другом ресурсе получила решение через Walker, возможно кому-то пригодится. Надеюсь, что автор кода будет не против если я выложу и тут :)

    Комментарий к коду: нужно было проходить рекурсивно по всем элементам меню и сохранять максимальную вложенность
    class example_walker extends Walker_Nav_Menu {
    
        // в этом свойстве сохраняем значение максимального вложения
        public $last_sub_menu_depth = 0;
    
        public function start_lvl( &$output, $depth = 0, $args = null ) {
            if ( isset( $args->item_spacing ) && 'discard' === $args->item_spacing ) {
                $t = '';
                $n = '';
            } else {
                $t = "\t";
                $n = "\n";
            }
            $indent = str_repeat( $t, $depth );
    
            // Default class.
            $classes = array( 'sub-menu' );
    
            // сравниваем текущее значение рекурсии с максимальным 
            if ( $depth === $this->last_sub_menu_depth ) {
                array_push( $classes, 'last-sub-menu' );
            }
    
            $class_names = join( ' ', apply_filters( 'nav_menu_submenu_css_class', $classes, $args, $depth ) );
            $class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : '';
    
            $output .= "{$n}{$indent}<ul$class_names>{$n}";
        }
    
        function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output ) {
            // обнуляем значение для текущего элемента и запускаем метод на подсчет максимального вложения, только когда элемент имеет дочерние элементы   
            if ( ! empty( $children_elements[ $element->{$this->db_fields['id']} ] ) ) {
                $this->last_sub_menu_depth = 0;
                $this->get_last_depth( $element, $children_elements, $max_depth, $depth );
            }
    
            return parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );
    
        }
    
        // метод для рекурсивного прохода по дочерним пунктам меню
        public function get_last_depth( $element, $children_elements, $max_depth, $depth ) {
            if ( ! $element ) {
                return;
            }
           
            $id_field = $this->db_fields['id'];
            $id = $element->$id_field;
    
            if ( ( 0 == $max_depth || $max_depth > $depth + 1 ) && isset( $children_elements[ $id ] ) ) {
                foreach ( $children_elements[ $id ] as $child ) {
                    $this->last_sub_menu_depth = $depth;
                    $this->get_last_depth( $child, $children_elements, $max_depth, $depth + 1 );
                }
            }
        }
    }
    Ответ написан
    Комментировать