Добавить div в конкретное подменю

Вопрос или проблема

Я исследовал в google, yandex, но безуспешно.

С помощью этого кода я могу установить div для подменю, но этот код добавляется ко всем подменю, мне нужно добавить div только к конкретному подменю.

class Megratron_div extends Walker_Nav_Menu
{
    function start_lvl( &$output, $depth = 0, $args = array() ) {
        $indent = str_repeat("\t", $depth);
        $output .= "\n$indent<div id='megatron'><ul class="sub-menu">\n";
    }
    function end_lvl( &$output, $depth = 0, $args = array() ) {
        $indent = str_repeat("\t", $depth);
        $output .= "$indent</ul></div>\n";
    }
}

Как я могу это сделать?

Я очень ценю вашу поддержку.

Класс Walker WordPress не передает необходимые вам аргументы в метод start_lvl(). Поэтому, чтобы сделать это, вам нужно добавить пользовательский метод display_element() в ваш пользовательский валькер. Вы можете использовать большинство оригинального кода, с чем-то подобным закомментированному ниже разделу:

public function display_element( $element, &$children_elements, $max_depth, $depth, $args, &$output ) {
    if ( ! $element ) {
        return;
    }

    $id_field = $this->db_fields['id'];
    $id       = $element->$id_field;

    //показать этот элемент
    $this->has_children = ! empty( $children_elements[ $id ] );
    if ( isset( $args[0] ) && is_array( $args[0] ) ) {
        $args[0]['has_children'] = $this->has_children; // Обратная совместимость.
    }

    $cb_args = array_merge( array( &$output, $element, $depth ), $args );
    call_user_func_array( array( $this, 'start_el' ), $cb_args );

    // спуститесь только тогда, когда глубина правильная и у этого элемента есть дети
    if ( ( $max_depth == 0 || $max_depth > $depth + 1 ) && isset( $children_elements[ $id ] ) ) {

        foreach ( $children_elements[ $id ] as $child ) {

            if ( ! isset( $newlevel ) ) {
                $newlevel = true;
                //начать разделитель дочернего элемента
                $cb_args = array_merge( array( &$output, $depth ), $args );

                /** Дополнительная проверка для пользовательского добавления id к подуровню */
                if ( $element->post_name="Megatron" ) {
                    $cb_args['sub_menu_id'] = 'megatron';
                }
                /** Завершение пользовательской проверки */

                call_user_func_array( array( $this, 'start_lvl' ), $cb_args );
            }
            $this->display_element( $child, $children_elements, $max_depth, $depth + 1, $args, $output );
        }
        unset( $children_elements[ $id ] );
    }

    if ( isset( $newlevel ) && $newlevel ) {
        //закончить разделитель дочернего элемента
        $cb_args = array_merge( array( &$output, $depth ), $args );
        call_user_func_array( array( $this, 'end_lvl' ), $cb_args );
    }

    //закончить этот элемент
    $cb_args = array_merge( array( &$output, $element, $depth ), $args );
    call_user_func_array( array( $this, 'end_el' ), $cb_args );
}

Добавленный код здесь проверяет имя вашего основного элемента, а затем добавляет информацию об id в аргументы, которые будут отправлены в start_lvl().

Теперь вы можете вывести правильную разметку в вашем методе start_lvl() с чем-то вроде:

public function start_lvl( &$output, $depth = 0, $args = array(), $sub_menu_div = null ) {
    $indent = str_repeat("\t", $depth);
    if ( $sub_menu_div ) {
        $output .= "\n$indent<div id=\"$sub_menu_div\"><ul class=\"sub-menu\">\n";
    } else {
        $output .= "\n$indent<ul class=\"sub-menu\">\n";
    }
}

Надеюсь, это поможет. Удачи!

Ответ или решение

Конечно, проблема, которую вы описали, касается кастомизации WordPress меню с использованием класса Walker_Nav_Menu, чтобы добавить div только к одному конкретному подменю. Это может быть затруднительно, поскольку стандартная реализация не передает необходимые аргументы в метод start_lvl(). Ниже рассматривается, как можно решить эту задачу, учитывая предоставленные данные и применяя нестандартный метод display_element().

Решение задачи

Шаг 1: Наследование от класса Walker_Nav_Menu

Начнем с наследования от класса Walker_Nav_Menu, чтобы создать наш собственный класс Megratron_div. Это позволит нам манипулировать методом display_element() для передачи дополнительных аргументов в start_lvl().

Шаг 2: Добавление метод display_element()

Метод display_element() необходимо переопределить, дабы мы могли определить, когда требуется добавить div к определенному подменю. Мы добавим условие, которое проверяет, когда к подменю должен быть добавлен div с заданным идентификатором.

public function display_element( $element, &$children_elements, $max_depth, $depth, $args, &$output ) {
    if ( ! $element ) {
        return;
    }

    $id_field = $this->db_fields['id'];
    $id = $element->$id_field;

    // Определяем, есть ли у элемента дочерние элементы
    $this->has_children = ! empty( $children_elements[ $id ] );
    if ( isset( $args[0] ) && is_array( $args[0] ) ) {
        $args[0]['has_children'] = $this->has_children;
    }

    $cb_args = array_merge( array( &$output, $element, $depth ), $args );
    call_user_func_array( array( $this, 'start_el' ), $cb_args );

    if ( ( $max_depth == 0 || $max_depth > $depth + 1 ) && isset( $children_elements[ $id ] ) ) {

        foreach ( $children_elements[ $id ] as $child ) {
            if ( ! isset( $newlevel ) ) {
                $newlevel = true;
                $cb_args = array_merge( array( &$output, $depth ), $args );

                // Добавляем проверку для динамического добавления ID к подменю
                if ( $element->post_name === "Megatron" ) {
                    $cb_args['sub_menu_id'] = 'megatron';
                }

                call_user_func_array( array( $this, 'start_lvl' ), $cb_args );
            }
            $this->display_element( $child, $children_elements, $max_depth, $depth + 1, $args, $output );
        }
        unset( $children_elements[ $id ] );
    }

    if ( isset( $newlevel ) && $newlevel ) {
        $cb_args = array_merge( array( &$output, $depth ), $args );
        call_user_func_array( array( $this, 'end_lvl' ), $cb_args );
    }

    $cb_args = array_merge( array( &$output, $element, $depth ), $args );
    call_user_func_array( array( $this, 'end_el' ), $cb_args );
}

Шаг 3: Изменение метода start_lvl()

Теперь метод start_lvl() может принимать аргумент $sub_menu_div, который будет содержать ID для подменю, если требуется.

public function start_lvl( &$output, $depth = 0, $args = array(), $sub_menu_div = null ) {
    $indent = str_repeat("\t", $depth);
    if ( $sub_menu_div ) {
        $output .= "\n$indent<div id=\"$sub_menu_div\"><ul class=\"sub-menu\">\n";
    } else {
        $output .= "\n$indent<ul class=\"sub-menu\">\n";
    }
}

Заключение

Использование модифицированного метода display_element() позволяет вам динамически добавлять div к определенным подменю, основываясь на специфичных атрибутах элемента. Это позволяет соблюдать уникальный подход в настройке меню в WordPress без внесения изменений сразу в каждое подменю. Надеюсь, это решение окажется полезным. Удачи в реализации!

Оцените материал
Добавить комментарий

Капча загружается...