Вопрос или проблема
У меня возникли проблемы с моим кодом walker для WordPress. Я знаю, что возможно вручную добавить пользовательский CSS-класс через раздел административного меню. Но я пытаюсь добиться автоматического добавления этого класса каждый раз, когда мой клиент добавляет страницу подменю.
Первый шаг, который я предпринял, заключался в том, чтобы заменить навигацию ul li
и изменить ее на стиль навигации a href
. Это работает. Теперь я ищу способ добавить класс к элементам подменю a href
…
Вот как в данный момент выглядит мой walker.
class Description_Walker extends Walker_Nav_Menu {
function start_el(&$output, $item, $depth, $args) {
$classes = empty($item->classes) ? array () : (array) $item->classes;
$class_names = join(' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) );
!empty ( $class_names ) and $class_names=" class="". esc_attr( $class_names ) . '"';
$output .= "";
$attributes="";
!empty( $item->attr_title ) and $attributes .= ' title="' . esc_attr( $item->attr_title ) .'"';
!empty( $item->target ) and $attributes .= ' target="' . esc_attr( $item->target ) .'"';
!empty( $item->xfn ) and $attributes .= ' rel="' . esc_attr( $item->xfn ) .'"';
!empty( $item->url ) and $attributes .= ' href="' . esc_attr( $item->url ) .'"';
$title = apply_filters( 'the_title', $item->title, $item->ID );
$item_output = $args->before
. "<a $attributes $class_names>"
. $args->link_before
. $title
. '</a>'
. $args->link_after
. $args->after;
if (array_search('menu-item-has-children', $item->classes)) {
$output .= sprintf("\n<div data-delay='0' class="w-dropdown"><div class="dropdown-toggle"><div class="icon icon-dropdown-toggle"></div><div>$title</div></div>
\n", ( array_search('current-menu-item', $item->classes) || array_search('current-page-parent', $item->classes) ) ? 'active' : '', $item->url,
$item->title);
} else {
$output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
}
}
function start_lvl(&$output, $depth, $args ) {
$indent = str_repeat("\t", $depth);
$output .= "\n$indent<nav class=\"dropdown-list\">\n<div class=\"submenu_speech\"></div>";
}
function end_lvl( &$output, $depth, $args = array() ) {
$indent = str_repeat("\t", $depth);
$output .= "$indent</nav></div>\n";
}
function end_el(&$output, $item, $depth, $args) {
$output .= "\n";
}
}
Существуют специальные фильтры для добавления классов к тегам ul
, li
или a
в меню.
Для тегов a
вы хотите использовать nav_menu_link_attributes
. Это позволяет вам изменять все атрибуты на теге a
, вот пример:
function my_nav_menu_link_attributes( $atts, $item, $args ) {
if ( 'main' === $args->theme_location ) {
if ( '0' === $item->menu_item_parent ) {
$atts['class'] = 'top-level-item';
}
}
return $atts;
}
add_filter( 'nav_menu_link_attributes', 'my_nav_menu_link_attributes', 10, 3 );
class Description_Walker extends Walker_Nav_Menu { function start_el(&$output, $item, $depth, $args) { $classes = empty($item->classes) ? array () : (array) $item->classes;
if( $depth == 1 ){ $class_names = join(' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) ); !empty ( $class_names ) and $class_names=" class="dropdown-link w-dropdown-link ". esc_attr( $class_names ) . '"'; } else { $class_names = join(' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) ); !empty ( $class_names ) and $class_names=" class="". esc_attr( $class_names ) . '"'; } $output .= ""; $attributes=""; !empty( $item->attr_title ) and $attributes .= ' title="' . esc_attr( $item->attr_title ) .'"'; !empty( $item->target ) and $attributes .= ' target="' . esc_attr( $item->target ) .'"'; !empty( $item->xfn ) and $attributes .= ' rel="' . esc_attr( $item->xfn ) .'"'; !empty( $item->url ) and $attributes .= ' href="' . esc_attr( $item->url ) .'"'; $title = apply_filters( 'the_title', $item->title, $item->ID ); $item_output = $args->before . "<a $attributes $class_names>" . $args->link_before . $title . '</a>' . $args->link_after . $args->after; if (array_search('menu-item-has-children', $item->classes)) { $output .= sprintf("\n<div data-delay='0' class="w-dropdown"><div class="dropdown-toggle w-dropdown-toggle"><div class="icon w-icon-dropdown-toggle"></div><div>$title</div></div> \n", ( array_search('current-menu-item', $item->classes) || array_search('current-page-parent', $item->classes) ) ? 'active' : '', $item->url, $item->title); } else { $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args ); } } function start_lvl(&$output, $depth, $args ) { $indent = str_repeat("\t", $depth); $output .= "\n$indent<nav class=\"dropdown-list w-dropdown-list\">\n<div class=\"submenu_speech\"></div>"; } function end_lvl( &$output, $depth, $args = array() ) { $indent = str_repeat("\t", $depth); $output .= "$indent</nav></div>\n"; } function end_el(&$output, $item, $depth, $args) { $output .= "\n"; }
}
Таким образом, когда $depth==1, к тегу a добавляется класс ‘dropdown-link w-dropdown-link’.
Это работает, но является ли это законным решением?
Ответ или решение
Ваш запрос касается изменения класса элементов подменю в WordPress с использованием кастомного класса "Walker". Вы сделали первый шаг, заменив традиционную структуру ul li
на ссылки (a href
), и теперь хотите добавить к подменю уникальный CSS класс. Это можно сделать при помощи вашего кастомного класса "Walker".
Шаги для реализации
-
Определение уровня подменю:
Ваша конструкцияif ($depth == 1)
правильно определяет, что мы находимся на уровне сразу под основным меню. Это необходимый условный оператор, который помогает назначить нужные классы именно для подменю. -
Добавление классов:
Вы можете использовать массив классов, уже назначенных для меню, и расширять его, добавляя собственные стилевые классы:if ($depth == 1) { $class_names = join(' ', apply_filters('nav_menu_css_class', array_filter($classes), $item)); !empty($class_names) and $class_names = ' class="dropdown-link w-dropdown-link ' . esc_attr($class_names) . '"'; } else { $class_names = join(' ', apply_filters('nav_menu_css_class', array_filter($classes), $item)); !empty($class_names) and $class_names = ' class="' . esc_attr($class_names) . '"'; }
-
Рендеринг элемента меню:
Используя$item_output
, вы создаете выходной элемент меню. Добавление атрибутов, таких какtitle
,target
,rel
, иhref
, происходит корректно и соответствует лучшим практикам.
Использование фильтров
Существует фильтр nav_menu_link_attributes
, который может быть полезен для добавления классов ко всем ссылкам меню. Это может упростить ваш код и сделать его более читаемым, особенно если у вас есть много элементов меню с разными атрибутами.
Пример использования:
function my_nav_menu_link_attributes($atts, $item, $args) {
if ($item->menu_item_parent) {
$atts['class'] = 'dropdown-link w-dropdown-link'; // Добавить класс для подменю
}
return $atts;
}
add_filter('nav_menu_link_attributes', 'my_nav_menu_link_attributes', 10, 3);
Заключение
Ваше текущее решение вполне законно, и оно делает именно то, что вы планировали. Исполняя ваши целевые требования, вы обеспечиваете, что классы для подменю добавляются автоматически. Использование как собственного класса Walker, так и фильтров WordPress дополнительно повышает гибкость и масштабируемость кода.
Для достижения оптимального результата рекомендуется также обращать внимание на кэширование ваших меню, чтобы предотвратить возможные проблемы с производительностью, особенно если места где эти меню используются, поддаются частому обновлению.
Если у вас возникнут дополнительные вопросы по данной теме, не стесняйтесь задать их.