Многоуровневая навигация — важный элемент любого сайта на WordPress, особенно если структура контента сложная и требует удобной организации меню. В этой статье рассмотрим, как создать кастомное многоуровневое меню без использования плагинов, используя только встроенные возможности темы и минимальный код. Это позволит избежать лишних зависимостей и повысить скорость загрузки сайта.
Основы работы с меню в WordPress
WordPress предоставляет встроенный функционал для создания и управления меню через админ-панель (Внешний вид > Меню). Однако по умолчанию тема должна поддерживать отображение меню и его многоуровневую структуру.
Чтобы тема поддерживала меню, в файле functions.php нужно зарегистрировать область меню с помощью функции register_nav_menus(). Например:
function wordpressa_register_menus() {
register_nav_menus(array(
'primary' => 'Главное меню',
));
}
add_action('after_setup_theme', 'wordpressa_register_menus');
Далее, в шаблоне (обычно header.php) добавляем вызов меню:
wp_nav_menu(array(
'theme_location' => 'primary',
'container' => 'nav',
'container_class' => 'main-navigation',
'menu_class' => 'menu',
));
Создание кастомного HTML и CSS для многоуровневого меню
По умолчанию WordPress строит вложенное меню с классами menu-item-has-children для пунктов с подменю, что позволяет стилизовать их через CSS.
Для многоуровневого меню важно корректно оформить стили для вложенных <ul> и <li> элементов, чтобы подменю раскрывались при наведении или клике.
Пример простого CSS для горизонтального многоуровневого меню:
.main-navigation ul {
list-style: none;
margin: 0;
padding: 0;
display: flex;
}
.main-navigation li {
position: relative;
}
.main-navigation ul ul {
display: none;
position: absolute;
top: 100%;
left: 0;
flex-direction: column;
background: #fff;
border: 1px solid #ccc;
z-index: 1000;
}
.main-navigation li:hover > ul {
display: flex;
}
.main-navigation ul ul ul {
left: 100%;
top: 0;
}
Такое оформление позволит при наведении мыши показывать подменю, а вложенные подменю будут выезжать вправо.
Добавление поддержки мобильного меню с раскрытием по клику
Для мобильных устройств часто требуется, чтобы подменю раскрывались по клику, а не по наведению. Это можно реализовать с помощью небольшого JavaScript, без плагинов.
Пример скрипта для раскрытия подменю:
document.addEventListener('DOMContentLoaded', function() {
const menuItems = document.querySelectorAll('.menu-item-has-children > a');
menuItems.forEach(function(item) {
item.addEventListener('click', function(e) {
e.preventDefault();
const parent = item.parentElement;
parent.classList.toggle('submenu-open');
});
});
});
CSS для отображения раскрытого меню:
.submenu-open > ul {
display: flex !important;
flex-direction: column;
}
Добавьте соответствующие медиазапросы для адаптивности меню.
Пример функции для вывода кастомного меню с дополнительными классами
Иногда требуется более тонкий контроль над выводом меню, например, добавить специальные классы или атрибуты для пунктов с подменю. Для этого можно написать кастомный walker.
Вот простой пример класса walker, который добавляет класс wordpressa-has-submenu для пунктов с подменю:
class Wordpressa_Walker_Nav_Menu extends Walker_Nav_Menu {
function start_lvl( &$output, $depth = 0, $args = null ) {
$indent = str_repeat("\t", $depth);
$output .= "\n$indent<ul class=\"sub-menu\">\n";
}
function start_el( &$output, $item, $depth = 0, $args = null, $id = 0 ) {
$classes = empty( $item->classes ) ? array() : (array) $item->classes;
if (in_array('menu-item-has-children', $classes)) {
$classes[] = 'wordpressa-has-submenu';
}
$class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args, $depth ) );
$class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : '';
$output .= "<li" . $class_names . ">";
$attributes = ! empty( $item->attr_title ) ? ' title="' . esc_attr( $item->attr_title ) . '"' : '';
$attributes .= ! empty( $item->target ) ? ' target="' . esc_attr( $item->target ) . '"' : '';
$attributes .= ! empty( $item->xfn ) ? ' rel="' . esc_attr( $item->xfn ) . '"' : '';
$attributes .= ! empty( $item->url ) ? ' href="' . esc_attr( $item->url ) . '"' : '';
$item_output = $args->before;
$item_output .= "<a" . $attributes . ">";
$item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
$item_output .= "</a>";
$item_output .= $args->after;
$output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
}
}
Используйте его при вызове меню:
wp_nav_menu(array(
'theme_location' => 'primary',
'walker' => new Wordpressa_Walker_Nav_Menu(),
));
Рекомендации по оптимизации и SEO для многоуровневого меню
Важно, чтобы меню было не только удобным для пользователей, но и правильно индексировалось поисковыми системами. Для этого:
- Используйте семантические теги — оборачивайте меню в
<nav>. - Добавляйте aria-атрибуты для доступности (например,
aria-haspopup="true"для пунктов с подменю). - Не перегружайте меню слишком большим количеством уровней — обычно 2-3 достаточно.
- Оптимизируйте CSS и JS, чтобы меню быстро загружалось и работало без задержек.
Использование плагинов для расширения функционала меню
Хотя наша задача — сделать меню без плагинов, иногда для сложных случаев удобно использовать специализированные решения. Например, плагин Clearfy Pro позволяет оптимизировать работу меню, убрать лишние классы и добавить удобные настройки.
Для визуального построения часто используют плагин Mega Menu, но это уже выходит за рамки статьи.
Итог
Создать многоуровневое меню в WordPress без плагинов вполне реально и несложно. Нужно:
- Зарегистрировать меню в теме.
- Добавить вызов меню в шаблон.
- Оформить CSS для вложенных списков.
- Добавить JS для мобильного раскрытия подменю.
- При необходимости написать кастомный walker для дополнительной гибкости.
Такое решение минимизирует зависимости, упрощает поддержку и ускоряет загрузку сайта.