Динамическое меню — одна из ключевых составляющих удобной навигации на сайте WordPress. В данной статье мы подробно разберём, как создать динамическое меню, используя системные хуки WordPress, что позволит менять структуру меню программно, в зависимости от условий или данных из базы. Такой подход полезен для сайтов с частой сменой структуры меню, или когда нужно показывать уникальный набор пунктов в зависимости от роли пользователя, текущей страницы или других параметров.
Почему стоит использовать хуки для создания динамического меню
Хуки (actions и filters) — это механизм WordPress для изменения поведения без изменения исходного кода ядра или темы. Для меню наиболее важен фильтр wp_nav_menu_items, который позволяет вмешаться в вывод пунктов меню и добавить, изменить или удалить элементы.
Использование хуков даёт следующие преимущества:
- Гибкость — меню меняется автоматически в зависимости от логики;
- Отделение логики от разметки — код более поддерживаемый;
- Возможность интеграции с плагинами и кастомным контентом;
- Удобство масштабирования и кастомизации.
Далее рассмотрим практические примеры.
Создание базового динамического пункта меню
Для начала добавим простой пункт в любое меню, используя фильтр wp_nav_menu_items. В functions.php вашей темы или в custom plugin добавьте следующий код:
function wpfinder_add_dynamic_menu_item($items, $args) {
if($args->theme_location == 'primary') { // проверяем, что это нужное меню
$dynamic_item = '<li class="menu-item"><a href="/special-offer">Специальное предложение</a></li>';
$items .= $dynamic_item; // добавляем пункт в конец
}
return $items;
}
add_filter('wp_nav_menu_items', 'wpfinder_add_dynamic_menu_item', 10, 2);
В этом примере мы добавляем в меню с локацией primary пункт со ссылкой на страницу «Специальное предложение». Таким образом, меню становится динамическим — вы можете менять этот код, чтобы добавлять пункты в зависимости от условий.
Динамическое меню с учётом роли пользователя
Часто нужно показывать разные пункты меню для гостей и авторизованных пользователей или по ролям. Добавим такой пример:
function wpfinder_role_based_menu_items($items, $args) {
if($args->theme_location == 'primary') {
if(is_user_logged_in()) {
$current_user = wp_get_current_user();
if(in_array('administrator', $current_user->roles)) {
$items .= '<li class="menu-item"><a href="/admin-panel">Панель администратора</a></li>';
} else {
$items .= '<li class="menu-item"><a href="/profile">Мой профиль</a></li>';
}
} else {
$items .= '<li class="menu-item"><a href="/login">Войти</a></li>';
}
}
return $items;
}
add_filter('wp_nav_menu_items', 'wpfinder_role_based_menu_items', 20, 2);
Здесь для администратора добавляется ссылка на панель администрирования, для обычного пользователя — на профиль, а для гостей — ссылка на страницу входа. Такая логика улучшает UX и помогает ориентироваться пользователям.
Создание подменю на основе произвольных записей
Допустим, у вас есть кастомный тип записи «Акции» (custom post type promo), и вы хотите подменю «Акции» в динамическом меню, которое автоматически обновляется при добавлении новых акций.
Пример кода:
function wpfinder_promos_submenu($items, $args) {
if($args->theme_location == 'primary') {
$promos = get_posts(array(
'post_type' => 'promo',
'numberposts' => 5,
'post_status' => 'publish',
));
$submenu = '<li class="menu-item menu-item-has-children"><a href="#">Акции</a><ul class="sub-menu">';
foreach($promos as $promo) {
$submenu .= '<li class="menu-item"><a href="'.get_permalink($promo->ID).'">'.esc_html($promo->post_title).'</a></li>';
}
$submenu .= '</ul></li>';
$items .= $submenu;
}
return $items;
}
add_filter('wp_nav_menu_items', 'wpfinder_promos_submenu', 30, 2);
Этот приём позволяет встроить динамическое подменю, которое обновляется автоматически, без ручного редактирования меню в админке.
Использование плагина ABC Pagination для структурирования меню с большим количеством записей
Если в вашем динамическом меню много пунктов, например, при создании подменю из большого количества объектов, удобно использовать постраничную навигацию прямо в меню. Плагин ABC Pagination поможет аккуратно разбить длинный список на страницы, улучшая юзабилити.
Для интеграции с меню можно получить текущую страницу из URL или параметров и отображать подменю соответствующей страницы.
Советы по оптимизации и поддержке динамических меню
При создании динамического меню стоит учитывать производительность. Частые запросы к базе данных в фильтрах меню могут замедлить загрузку. Рекомендуется кэшировать результаты с помощью Transient API:
function wpfinder_get_cached_promos_menu() {
$cache_key = 'wpfinder_promos_menu';
$menu_cache = get_transient($cache_key);
if(false === $menu_cache) {
$promos = get_posts(array('post_type' => 'promo', 'numberposts' => 5, 'post_status' => 'publish'));
$menu_html = '';
foreach($promos as $promo) {
$menu_html .= '<li class="menu-item"><a href="'.get_permalink($promo->ID).'">'.esc_html($promo->post_title).'</a></li>';
}
set_transient($cache_key, $menu_html, 3600); // кэш на час
return $menu_html;
}
return $menu_cache;
}
Использование кеша уменьшает нагрузку на сервер и ускоряет генерацию меню.
Итоги: динамическое меню — мощный инструмент программной навигации
Мы рассмотрели, как с помощью фильтра wp_nav_menu_items создавать динамические меню в WordPress, ориентируясь на роль пользователя, данные из кастомных типов записей и другие условия. Такой подход позволяет создавать гибкие и адаптивные меню без ручного редактирования в панели администратора.
Для более сложных кейсов можно использовать сторонние плагины, такие как ABC Pagination для удобной навигации в длинных меню, а также внедрять кэширование на базе Transient API для повышения производительности.
Освоив динамические меню с хуками, вы сможете существенно улучшить пользовательский опыт и гибкость управления навигацией на вашем WordPress-сайте.