Введение в динамические меню WordPress и их адаптивность
Меню — ключевой элемент навигации любого сайта на WordPress. Часто возникает задача не просто добавить статическое меню, а сделать его динамическим, адаптирующимся под устройство пользователя и удобным для редактирования через админку. В этой статье мы разберем, как создать собственное динамическое меню с адаптивной версткой, используя встроенные возможности WordPress и немного PHP-кода.
Для начала важно понимать, что WordPress уже поддерживает динамические меню через wp_nav_menu(). Однако, по умолчанию, это меню не всегда удобно использовать в адаптивном дизайне без дополнительной кастомизации. Мы рассмотрим, как расширить стандартный функционал, чтобы меню автоматически подстраивалось под мобильные устройства и было удобным для пользователя.
В ходе статьи приведем примеры кода, которые помогут реализовать полноценное меню с выпадающими пунктами, переключателем для мобильных устройств и кастомным walker-классом для точного контроля над HTML-разметкой.
Регистрация и вывод динамического меню в WordPress
Как зарегистрировать меню в теме
Первый шаг — зарегистрировать меню в файле functions.php вашей темы или дочерней темы. Это делается с помощью функции register_nav_menus():
function wpcompany_register_menus() {
register_nav_menus([
'primary-menu' => 'Главное меню'
]);
}
add_action('after_setup_theme', 'wpcompany_register_menus');После этого меню можно создать и отредактировать в админке WordPress в разделе «Внешний вид > Меню».
Вывод меню в шаблоне
Для вывода меню используем функцию wp_nav_menu() с кастомными параметрами:
wp_nav_menu([
'theme_location' => 'primary-menu',
'container' => 'nav',
'container_class' => 'main-navigation',
'menu_class' => 'menu',
'fallback_cb' => false
]);Здесь мы задаем HTML-элемент <nav> с классом main-navigation, а сам список меню будет иметь класс menu. Параметр fallback_cb отключает вывод страниц, если меню не назначено.
Создание адаптивного меню: переключатель и стили
Добавление кнопки-бургера для мобильных устройств
Чтобы меню было удобным на мобильных, необходимо добавить кнопку для открытия и закрытия меню — так называемый «бургер». Добавим в шаблон рядом с меню следующий HTML:
<button class="menu-toggle" aria-controls="primary-menu" aria-expanded="false">
<span class="screen-reader-text">Открыть меню</span>
☰
</button>Эту кнопку мы будем использовать с помощью JavaScript для показа и скрытия меню.
CSS для адаптивности меню
Далее пишем CSS, который скрывает меню на маленьких экранах и показывает кнопку:
@media (max-width: 768px) {
.main-navigation .menu {
display: none;
flex-direction: column;
background-color: #fff;
position: absolute;
width: 100%;
top: 100%;
left: 0;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
}
.menu-toggle {
display: block;
background: none;
border: none;
font-size: 1.5em;
cursor: pointer;
}
}На экранах шириной меньше 768px меню скрыто по умолчанию, а кнопка бургера видна.
JavaScript для управления меню
Добавим простой скрипт, который переключает видимость меню при клике на кнопку:
document.addEventListener('DOMContentLoaded', function() {
const toggleButton = document.querySelector('.menu-toggle');
const menu = document.querySelector('.main-navigation .menu');
toggleButton.addEventListener('click', function() {
const isExpanded = this.getAttribute('aria-expanded') === 'true';
this.setAttribute('aria-expanded', !isExpanded);
if (menu.style.display === 'flex') {
menu.style.display = 'none';
} else {
menu.style.display = 'flex';
}
});
});Кастомизация меню с помощью Walker класса
Зачем нужен Walker и как его использовать
Иногда стандартный вывод меню не подходит по структуре HTML или стилям. Тогда создают собственный класс-наследник Walker_Nav_Menu, который управляет генерацией каждого элемента меню.
Например, чтобы добавить иконки к пунктам меню или изменить структуру вложенных списков, создадим класс WPCompany_Walker_Nav_Menu:
class WPCompany_Walker_Nav_Menu extends Walker_Nav_Menu {
function start_el(&$output, $item, $depth = 0, $args = null, $id = 0) {
$classes = empty($item->classes) ? array() : (array) $item->classes;
$class_names = join(' ', apply_filters('nav_menu_css_class', array_filter($classes), $item));
$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) . '"' : '';
$icon = '';
if (in_array('menu-item-has-children', $classes)) {
$icon = '<span class="submenu-icon">▾</span>';
}
$item_output = $args->before;
$item_output .= '<a' . $attributes . '>' . $args->link_before . apply_filters('the_title', $item->title, $item->ID) . $args->link_after . $icon . '</a>';
$item_output .= $args->after;
$output .= apply_filters('walker_nav_menu_start_el', $item_output, $item, $depth, $args);
}
}В этом примере мы добавляем стрелку-подсказку к пунктам, у которых есть дочерние элементы.
Подключение кастомного Walker
Для использования нашего класса передаем его в параметр walker:
wp_nav_menu([
'theme_location' => 'primary-menu',
'container' => 'nav',
'container_class' => 'main-navigation',
'menu_class' => 'menu',
'walker' => new WPCompany_Walker_Nav_Menu(),
'fallback_cb' => false
]);Дополнительные полезные советы и плагины для меню
Использование плагинов для расширения меню
Если хочется быстро получить расширенные возможности, можно воспользоваться плагинами. Например:
- Max Mega Menu — мощный плагин для создания мегаменю с адаптивной версткой;
- Clearfy Pro — оптимизирует работу сайта и может помочь с производительностью меню;
- WPGPT может использоваться для генерации подсказок и описаний пунктов меню в админке.
Оптимизация производительности меню
Большие меню могут замедлять загрузку страниц. Для ускорения стоит:
- Кэшировать вывод меню с помощью transient API или плагинов кэширования;
- Минимизировать количество вложенных пунктов;
- Использовать ленивую загрузку и асинхронный JavaScript.
Пример кода для кэширования меню:
function wpcompany_get_cached_menu() {
$cache_key = 'wpcompany_primary_menu';
$menu = get_transient($cache_key);
if (false === $menu) {
ob_start();
wp_nav_menu([
'theme_location' => 'primary-menu',
'container' => false,
'fallback_cb' => false
]);
$menu = ob_get_clean();
set_transient($cache_key, $menu, HOUR_IN_SECONDS);
}
echo $menu;
}
add_action('wp_footer', 'wpcompany_get_cached_menu');