Почему стоит создавать многоуровневое меню вручную в WordPress
Стандартные возможности WordPress позволяют создавать меню через админ-панель, но часто это не хватает для реализации сложных многоуровневых структур с кастомным выводом и функционалом. Автоматические методы, например, использование wp_nav_menu, дают базовый результат, но если нужно полностью контролировать HTML-разметку, добавлять уникальные CSS-классы или внедрять дополнительные элементы, то лучше написать собственный генератор меню на PHP.
Создание многоуровневого меню вручную позволит вам:
- Гибко управлять вложенностью и структурой;
- Добавлять уникальные атрибуты и классы для стилизации;
- Встраивать дополнительные элементы, например иконки или индикаторы подменю;
- Оптимизировать производительность, минимизируя лишние запросы к базе.
В этой статье мы разберём, как на примере создать кастомный многоуровневый список меню с помощью рекурсивной функции.
Подготовка данных меню: получение элементов
Для начала нам нужно получить все пункты меню WordPress для заданного меню. Для этого используется функция wp_get_nav_menu_items(). Она возвращает массив объектов, описывающих пункты меню, включая их ID, родителя, URL и название.
Пример получения пунктов меню:
$menu_name = 'primary'; // Название меню<br>$locations = get_nav_menu_locations();<br>if ( isset($locations[$menu_name]) ) {<br> $menu = wp_get_nav_menu_object( $locations[$menu_name] );<br> $menu_items = wp_get_nav_menu_items( $menu->term_id );<br>} else {<br> $menu_items = [];<br>}Важно: для работы этого кода меню с указанным именем должно быть зарегистрировано и назначено в админке WordPress.
Рекурсивная функция для вывода многоуровневого меню
Для построения иерархии меню на основе массива пунктов используем рекурсивную функцию, которая выводит <ul> и <li> с вложенностью.
Ключевой момент — фильтровать пункты меню по родителю, чтобы правильно строить дерево.
function wporg_render_menu_level($menu_items, $parent_id = 0) {<br> $html = '<ul>';<br> foreach ($menu_items as $item) {<br> if (intval($item->menu_item_parent) === $parent_id) {<br> $has_children = false;<br> foreach ($menu_items as $child_item) {<br> if (intval($child_item->menu_item_parent) === intval($item->ID)) {<br> $has_children = true;<br> break;<br> }<br> }<br> $class = $has_children ? 'class="has-children"' : '';<br> $html .= '<li ' . $class . '>';<br> $html .= '<a href="' . esc_url($item->url) . '">' . esc_html($item->title) . '</a>';<br> if ($has_children) {<br> $html .= wporg_render_menu_level($menu_items, intval($item->ID));<br> }<br> $html .= '</li>';<br> }<br> }<br> $html .= '</ul>';<br> return $html;<br>}Функция принимает весь список пунктов меню и ID родителя для текущего уровня (по умолчанию 0 — корневой уровень). Для каждого пункта проверяется, есть ли у него дочерние элементы, и если да, вызывается функция рекурсивно для вложенного списка.
Пример использования функции и вывод меню на сайте
Объединим получение пунктов меню и вызов рекурсивной функции для вывода. Добавим проверку, чтобы избежать ошибок, если меню не назначено.
function wporg_display_custom_menu() {<br> $menu_name = 'primary';<br> $locations = get_nav_menu_locations();<br> if ( ! isset($locations[$menu_name]) ) {<br> echo '<p>Меню "' . esc_html($menu_name) . '" не назначено.</p>';<br> return;<br> }<br> $menu = wp_get_nav_menu_object($locations[$menu_name]);<br> $menu_items = wp_get_nav_menu_items($menu->term_id);<br> if ( empty($menu_items) ) {<br> echo '<p>Пункты меню отсутствуют.</p>';<br> return;<br> }<br> echo wporg_render_menu_level($menu_items);<br>}<br><br>// Вызов функции, например, в шаблоне header.php<br>wporg_display_custom_menu();Этот код выведет многоуровневое меню в виде вложенного списка. Для стилизации можно использовать CSS, например, скрывать вложенные списки и показывать их при наведении на родителя.
Поддержка адаптивности и стилей для многоуровневого меню
Чтобы меню выглядело красиво и было удобным на мобильных устройствах, рекомендуем добавить CSS для управления отображением подменю. Например:
.has-children > ul {<br> display: none;<br> position: absolute;<br> background: #fff;<br> padding: 10px;<br> box-shadow: 0 2px 8px rgba(0,0,0,0.15);<br>}<br>.has-children:hover > ul {<br> display: block;<br>}<br>ul {<br> list-style: none;<br> margin: 0;<br> padding: 0;<br>}<br>li {<br> position: relative;<br> padding: 5px 10px;<br>}<br>a {<br> text-decoration: none;<br> color: #333;<br>}<br>@media (max-width: 768px) {<br> .has-children > ul {<br> position: static;<br> display: none;<br> }<br> .has-children.active > ul {<br> display: block;<br> }<br>}Чтобы сделать подменю открывающимися по клику на мобильных устройствах, можно подключить небольшой jQuery-скрипт:
jQuery(document).ready(function($) {<br> $('.has-children > a').on('click', function(e) {<br> if ($(window).width() <= 768) {<br> e.preventDefault();<br> $(this).parent().toggleClass('active');<br> }<br> });<br>});<Плагины для расширения функционала меню
Если вы не хотите писать код самостоятельно или требуется более сложный функционал, можно использовать плагины с поддержкой многоуровневых меню:
- Max Mega Menu — мощный плагин для создания мегаменю с визуальным редактором и поддержкой вложенности;
- WP Mega Menu — позволяет создавать красивые выпадающие меню с виджетами и настройками;
- UberMenu — премиум-плагин с расширенным функционалом и адаптивным дизайном.
Все эти плагины прекрасно справляются с задачей создания многоуровневых меню и могут быть расширены за счёт собственных стилей и скриптов.
Заключение
Создание многоуровневого меню в WordPress с помощью кода — это мощный метод, который даст полный контроль над выводом и стилями. Мы показали, как получить пункты меню, построить рекурсивную функцию для вывода вложенных списков и обеспечить адаптивность с помощью CSS и JavaScript. Такой подход полезен при разработке уникальных тем и кастомных решений.