Вопрос или проблема
Я исследовал в 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 без внесения изменений сразу в каждое подменю. Надеюсь, это решение окажется полезным. Удачи в реализации!