Зачем создавать собственное меню выпадающего списка в WordPress
Иногда стандартные возможности меню WordPress не позволяют реализовать желаемый дизайн или функциональность. Особенно это касается выпадающих списков, где нужно добавить кастомное поведение, стили или динамическую подгрузку пунктов. В таких случаях полезно знать, как самостоятельно создавать меню на PHP с поддержкой JavaScript для интерактивности.
Это важно для уникальных тем и плагинов, когда хочется избежать громоздких решений и оставить код легким и понятным.
Создание базового меню с выпадающими элементами на PHP
Начнем с того, как на PHP в WordPress вывести меню, в котором есть вложенные пункты — классический выпадающий список. В WordPress меню создаются через wp_nav_menu, но чтобы получить полный контроль, можно написать свою функцию для вывода.
Пример функции wptest_render_dropdown_menu, которая выводит меню с вложенными элементами:
function wptest_render_dropdown_menu($menu_name) {
$locations = get_nav_menu_locations();
if (!isset($locations[$menu_name])) {
echo 'Меню не найдено';
return;
}
$menu = wp_get_nav_menu_object($locations[$menu_name]);
$menu_items = wp_get_nav_menu_items($menu->term_id);
// Собираем элементы в дерево
$tree = [];
foreach ($menu_items as $item) {
$tree[$item->menu_item_parent][] = $item;
}
echo '<ul class="wptest-menu">';
if (isset($tree[0])) {
foreach ($tree[0] as $parent) {
$has_children = isset($tree[$parent->ID]);
echo '<li class="wptest-menu-item'.($has_children ? ' has-children' : '').'">';
echo '<a href="'.esc_url($parent->url).'">'.esc_html($parent->title).'</a>';
if ($has_children) {
echo '<ul class="wptest-submenu">';
foreach ($tree[$parent->ID] as $child) {
echo '<li><a href="'.esc_url($child->url).'">'.esc_html($child->title).'</a></li>';
}
echo '</ul>';
}
echo '</li>';
}
}
echo '</ul>';
}
Здесь мы вручную собираем дерево меню и выводим список с классами для вложенных элементов. Это даст нам основу для стилизации и добавления JavaScript.
Добавление интерактивности выпадающего меню через JavaScript
В стандартном HTML меню с вложенными списками не всегда удобно раскрывать подменю. Добавим скрипт, который будет открывать и закрывать подменю по клику, что особенно полезно на мобильных устройствах.
Пример простого JavaScript для раскрытия вложенных списков:
document.addEventListener('DOMContentLoaded', function() {
const toggles = document.querySelectorAll('.wptest-menu-item.has-children > a');
toggles.forEach(function(toggle) {
toggle.addEventListener('click', function(e) {
e.preventDefault();
const parentLi = this.parentElement;
parentLi.classList.toggle('open');
});
});
});
Этот код ищет все пункты с классом has-children, и при клике на ссылку переключает класс open, который мы используем для отображения подменю через CSS.
CSS для выпадающего меню и адаптивности
Чтобы меню выглядело и работало правильно, добавим базовые стили:
.wptest-menu {
list-style: none;
margin: 0;
padding: 0;
display: flex;
}
.wptest-menu-item {
position: relative;
margin-right: 20px;
}
.wptest-submenu {
display: none;
position: absolute;
top: 100%;
left: 0;
list-style: none;
margin: 0;
padding: 10px 0;
background: #fff;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
}
.wptest-menu-item.open > .wptest-submenu {
display: block;
}
.wptest-menu-item > a {
text-decoration: none;
padding: 10px 15px;
display: block;
color: #333;
}
Можно дополнительно расширить стили для мобильных экранов с помощью медиазапросов, чтобы меню переходило в вертикальный список с выпадающими подменю.
Пример использования функции и подключения скрипта и стилей
Для вывода меню в теме используйте:
<?php wptest_render_dropdown_menu('primary'); ?>
где primary — это локация меню, зарегистрированная в вашей теме.
Подключите JavaScript и CSS в functions.php вашей темы:
function wptest_enqueue_menu_scripts() {
wp_enqueue_style('wptest-menu-style', get_template_directory_uri() . '/css/wptest-menu.css');
wp_enqueue_script('wptest-menu-script', get_template_directory_uri() . '/js/wptest-menu.js', [], false, true);
}
add_action('wp_enqueue_scripts', 'wptest_enqueue_menu_scripts');
Расширение функционала: динамическая подгрузка пунктов меню через AJAX
Для сложных сайтов может понадобиться подгружать пункты меню динамически, например, в зависимости от категории или пользователя. В этом случае можно использовать AJAX-запросы WordPress.
Пример простого AJAX-обработчика, который возвращает HTML подменю:
add_action('wp_ajax_wptest_load_submenu', 'wptest_load_submenu');
add_action('wp_ajax_nopriv_wptest_load_submenu', 'wptest_load_submenu');
function wptest_load_submenu() {
$parent_id = intval($_POST['parent_id']);
if (!$parent_id) {
wp_send_json_error('Неверный ID');
}
$submenu_items = wp_get_nav_menu_items(get_nav_menu_locations()['primary']);
$children = array_filter($submenu_items, function($item) use ($parent_id) {
return $item->menu_item_parent == $parent_id;
});
if (empty($children)) {
wp_send_json_success('');
}
ob_start();
echo '<ul class="wptest-submenu">';
foreach ($children as $child) {
echo '<li><a href="'.esc_url($child->url).'">'.esc_html($child->title).'</a></li>';
}
echo '</ul>';
$html = ob_get_clean();
wp_send_json_success($html);
}
JavaScript можно доработать, чтобы клик по родителю отправлял AJAX и подгружал подменю на лету. Это разгружает страницу и позволяет делать меню более динамичным.
Полезные плагины для управления меню и кастомизации
Для дополнения функционала можно использовать плагины, например:
- Clearfy Pro — оптимизация и расширение возможностей WordPress, включая работу с меню.
- WPStories — для создания интерактивных историй, может использоваться для дополнительной навигации.
Эти плагины помогут улучшить UX и расширить функциональность вашего сайта на WordPress.