Как правильно сделать двухуровневое меню wordpress?
Не могу сделать двухуровневое меню, подскажите пожалуйста как правильнее сделать?
Нужно сделать такое меню
<nav class="nav"> <div class="nav__wrapper"> <ul class="nav__list nav-list"> <li class="nav-list__item nav-list__item--toggle"> <a href="#" class="nav-list__link">Открыть меню</a> <div class="nav-list__icon"></div> </li> <li class="nav-list__item"> <a href="#" class="nav-list__link">Гидроизоляция </a> <span class="nav-list__icon"></span> <ul class="nav-sublist"> <li class="nav-sublist__item"> <p class="nav-sublist__title">Популярные услуги:</p> </li> <li class="nav-sublist__item"> <a href="#" class="nav-sublist__link">Гидроизоляция кровли</a> </li> <li> <a href="#" class="nav-sublist__button">Посмотреть все услуги</a> </li> </ul> </li> </ul> </div> </nav> |
<nav class="nav"> <div class="nav__wrapper"> <ul class="nav__list nav-list"> <li class="nav-list__item nav-list__item--toggle"> <a href="#" class="nav-list__link">Открыть меню</a> <div class="nav-list__icon"></div> </li> <li class="nav-list__item"> <a href="#" class="nav-list__link">Гидроизоляция </a> <span class="nav-list__icon"></span> <ul class="nav-sublist"> <li class="nav-sublist__item"> <p class="nav-sublist__title">Популярные услуги:</p> </li> <li class="nav-sublist__item"> <a href="#" class="nav-sublist__link">Гидроизоляция кровли</a> </li> <li> <a href="#" class="nav-sublist__button">Посмотреть все услуги</a> </li> </ul> </li> </ul> </div> </nav>
Что не получается, не могу добавить первым пунктом для мобильных
<li class="nav-list__item nav-list__item--toggle"> <a href="#" class="nav-list__link">Открыть меню</a> <div class="nav-list__icon"></div> </li> |
<li class="nav-list__item nav-list__item--toggle"> <a href="#" class="nav-list__link">Открыть меню</a> <div class="nav-list__icon"></div> </li>
Если меню двухуровневое то не могу добавить после a
<span class="nav-list__icon"></span>
добавить
<li class="nav-sublist__item"> <p class="nav-sublist__title">Популярные услуги:</p> </li> |
<li class="nav-sublist__item"> <p class="nav-sublist__title">Популярные услуги:</p> </li>
и поменять стили для li a в двухуровневых
Делаю так
<nav id="menu" class="nav" role="navigation" itemscope itemtype="https://schema.org/SiteNavigationElement"> <?php wp_nav_menu( array( 'menu' => 'main-menu', // (string) Название выводимого меню (указывается в админке при создании меню, приоритетнее чем указанное местоположение theme_location - если указано, то параметр theme_location игнорируется) 'container' => 'div', // (string) Контейнер меню. Обворачиватель ul. Указывается тег контейнера (по умолчанию в тег div) 'container_class' => 'nav__wrapper', // (string) class контейнера (div тега) 'container_id' => '', // (string) id контейнера (div тега) 'menu_class' => 'nav__list nav-list', // (string) class самого меню (ul тега) 'menu_id' => '', // (string) id самого меню (ul тега) 'echo' => true, // (boolean) Выводить на экран или возвращать для обработки 'fallback_cb' => 'wp_page_menu', // (string) Используемая (резервная) функция, если меню не существует (не удалось получить) 'before' => '', // (string) Текст перед <a> каждой ссылки 'after' => '', // (string) Текст после </a> каждой ссылки 'link_before' => '', // (string) Текст перед анкором (текстом) ссылки 'link_after' => '', // (string) Текст после анкора (текста) ссылки 'items_wrap' => '<ul id="%1$s" class="%2$s">%3$s</ul>', 'depth' => 0, 'add_li_class' => 'nav-list__item',// (integer) Глубина вложенности (0 - неограничена, 2 - двухуровневое меню) 'walker' => '' // (object) Класс собирающий меню. Default: new Walker_Nav_Menu ) ); ?> </nav> |
<nav id="menu" class="nav" role="navigation" itemscope itemtype="https://schema.org/SiteNavigationElement"> <?php wp_nav_menu( array( 'menu' => 'main-menu', // (string) Название выводимого меню (указывается в админке при создании меню, приоритетнее чем указанное местоположение theme_location - если указано, то параметр theme_location игнорируется) 'container' => 'div', // (string) Контейнер меню. Обворачиватель ul. Указывается тег контейнера (по умолчанию в тег div) 'container_class' => 'nav__wrapper', // (string) class контейнера (div тега) 'container_id' => '', // (string) id контейнера (div тега) 'menu_class' => 'nav__list nav-list', // (string) class самого меню (ul тега) 'menu_id' => '', // (string) id самого меню (ul тега) 'echo' => true, // (boolean) Выводить на экран или возвращать для обработки 'fallback_cb' => 'wp_page_menu', // (string) Используемая (резервная) функция, если меню не существует (не удалось получить) 'before' => '', // (string) Текст перед <a> каждой ссылки 'after' => '', // (string) Текст после </a> каждой ссылки 'link_before' => '', // (string) Текст перед анкором (текстом) ссылки 'link_after' => '', // (string) Текст после анкора (текста) ссылки 'items_wrap' => '<ul id="%1$s" class="%2$s">%3$s</ul>', 'depth' => 0, 'add_li_class' => 'nav-list__item',// (integer) Глубина вложенности (0 - неограничена, 2 - двухуровневое меню) 'walker' => '' // (object) Класс собирающий меню. Default: new Walker_Nav_Menu ) ); ?> </nav>
в functions.php
function theme_add_anchor_links($classes, $item, $args) { $classes['class'] = "nav-list__link"; return $classes; } add_filter("nav_menu_link_attributes", "theme_add_anchor_links", 1, 3); function add_additional_class_on_li($classes, $item, $args) { if(isset($args->add_li_class)) { $classes[] = $args->add_li_class; } return $classes; } add_filter('nav_menu_css_class', 'add_additional_class_on_li', 1, 3); add_filter( 'nav_menu_submenu_css_class', 'change_wp_nav_menu', 10, 3 ); function change_wp_nav_menu( $classes, $args, $depth ) { foreach ( $classes as $key => $class ) { if ( $class == 'sub-menu' ) { $classes[ $key ] = 'nav-sublist'; } } return $classes; } |
function theme_add_anchor_links($classes, $item, $args) { $classes['class'] = "nav-list__link"; return $classes; } add_filter("nav_menu_link_attributes", "theme_add_anchor_links", 1, 3); function add_additional_class_on_li($classes, $item, $args) { if(isset($args->add_li_class)) { $classes[] = $args->add_li_class; } return $classes; } add_filter('nav_menu_css_class', 'add_additional_class_on_li', 1, 3); add_filter( 'nav_menu_submenu_css_class', 'change_wp_nav_menu', 10, 3 ); function change_wp_nav_menu( $classes, $args, $depth ) { foreach ( $classes as $key => $class ) { if ( $class == 'sub-menu' ) { $classes[ $key ] = 'nav-sublist'; } } return $classes; }
Дополнительно:
Послушай добрый совет - выкинь это и используй родные механизмы ВП. По максимуму. (страшно представить что ты ещё навял, если даже меню додумался ВРУЧНУЮ прописывать в коде)
4 варианта на вскидку
1) написать extends Walker_Nav_Menu
2) собрать меню через wp_get_nav_menu_items
3) правильно и вдумчиво использовать хуки из стандартного Walker_Nav_Menu
4) сходить на фриланс и нанять там того кто умеет
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос


Двухуровневое меню в WordPress лучше делать через стандартное меню WordPress, а не собирать пункты вручную в шаблоне. В админке создаёте меню, вкладываете дочерние пункты перетаскиванием, а в теме выводите через
wp_nav_menu(). WordPress сам добавит классы для вложенных списков.wp_nav_menu([ 'theme_location' => 'primary', 'container' => 'nav', 'container_class' => 'site-nav', 'menu_class' => 'site-nav__list', 'depth' => 2, ]);
Для регистрации области меню:
add_action('after_setup_theme', function () { register_nav_menus([ 'primary' => 'Главное меню', ]); });
Базовая CSS-логика для второго уровня:
.site-nav__list { display: flex; gap: 24px; list-style: none; } .site-nav li { position: relative; } .site-nav .sub-menu { display: none; position: absolute; top: 100%; left: 0; min-width: 220px; padding: 10px; background: #fff; box-shadow: 0 12px 30px rgba(0,0,0,.12); list-style: none; z-index: 20; } .site-nav li:hover > .sub-menu, .site-nav li:focus-within > .sub-menu { display: block; }
Если нужен строго свой HTML, тогда пишется кастомный
Walker_Nav_Menu, но для обычного двухуровневого меню это лишнее. Начните со стандартного вывода и CSS. Так сохранится управление из админки, активные классы, доступность и совместимость с плагинами.На мобильной версии второй уровень лучше не открывать через hover. Сделайте кнопку-стрелку или раскрытие по клику, иначе пользователи на телефоне будут случайно переходить по родительскому пункту. Также добавьте состояние
focus-within, чтобы меню было доступно с клавиатуры.Если меню должно открываться мегаменю с колонками, всё равно можно оставить WordPress Menu как источник данных, а внешний вид собрать CSS Grid или кастомным walker. Главное — не хардкодить ссылки в шаблоне, иначе менеджер не сможет нормально управлять структурой через админку.