В современных проектах на WordPress часто возникает необходимость создать удобное вложенное меню, которое динамически подгружает свои дочерние пункты без перезагрузки страницы. Это улучшает пользовательский опыт, особенно если меню большое и содержит много уровней вложенности.
Почему стоит использовать AJAX для вложенных меню в WordPress
Стандартное меню WordPress выводится целиком на странице, что приводит к увеличению времени загрузки и усложняет навигацию, если пунктов много. С помощью AJAX можно подгружать дочерние пункты только по запросу пользователя — например, при клике на родительский элемент.
Такой подход значительно сокращает объем передаваемых данных и ускоряет отклик интерфейса. Кроме того, AJAX позволяет реализовать кастомную логику отображения меню, которую сложно сделать с помощью стандартных функций.
В этом руководстве мы рассмотрим, как создать вложенное меню с подгрузкой дочерних элементов через AJAX, используя собственные хуки WordPress и API REST.
Создание структуры меню и регистрация локации
Для начала регистрируем локацию меню в файле темы functions.php:
function wpdesk_register_my_menu() {
register_nav_menu('wpdesk-ajax-menu', __('WPDesk AJAX Menu'));
}
add_action('init', 'wpdesk_register_my_menu');После этого создайте меню в админке WordPress и добавьте туда пункты с нужной иерархией. В дальнейшем мы будем динамически подгружать дочерние элементы.
Вывод базового меню с контейнером для AJAX
В шаблоне, например, header.php, выводим базовое меню первого уровня:
wp_nav_menu(array(
'theme_location' => 'wpdesk-ajax-menu',
'container' => 'nav',
'container_id' => 'wpdesk-ajax-menu-container',
'menu_class' => 'wpdesk-ajax-menu',
'depth' => 1, // Выводим только первый уровень
));Каждому пункту меню добавим класс и data-атрибут с ID записи, чтобы по нему можно было запрашивать дочерние пункты через AJAX.
Создаем JavaScript для подгрузки дочерних пунктов
Подключите скрипт, который будет слушать клики по пунктам меню и отправлять AJAX-запросы:
function wpdesk_enqueue_ajax_menu_script() {
wp_enqueue_script('wpdesk-ajax-menu', get_template_directory_uri() . '/js/wpdesk-ajax-menu.js', array('jquery'), '1.0', true);
wp_localize_script('wpdesk-ajax-menu', 'wpdeskAjaxMenu', array(
'ajaxurl' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('wpdesk_ajax_menu_nonce')
));
}
add_action('wp_enqueue_scripts', 'wpdesk_enqueue_ajax_menu_script');В файле js/wpdesk-ajax-menu.js:
jQuery(document).ready(function($) {
$('.wpdesk-ajax-menu li.menu-item').on('click', '> a', function(e) {
e.preventDefault();
var menuItem = $(this).parent();
var parentId = menuItem.data('id');
if (menuItem.hasClass('loaded')) {
menuItem.children('ul').toggle();
return;
}
$.ajax({
url: wpdeskAjaxMenu.ajaxurl,
method: 'POST',
data: {
action: 'wpdesk_load_submenu',
parent_id: parentId,
nonce: wpdeskAjaxMenu.nonce
},
success: function(response) {
if (response.success) {
menuItem.append(response.data);
menuItem.addClass('loaded');
}
}
});
});
});Обработка AJAX-запроса в PHP
Добавим обработчик, который вернет дочерние пункты меню по ID родителя:
function wpdesk_ajax_load_submenu() {
check_ajax_referer('wpdesk_ajax_menu_nonce', 'nonce');
$parent_id = isset($_POST['parent_id']) ? intval($_POST['parent_id']) : 0;
if (!$parent_id) {
wp_send_json_error('Invalid parent ID');
}
$locations = get_nav_menu_locations();
if (empty($locations['wpdesk-ajax-menu'])) {
wp_send_json_error('Menu not found');
}
$menu = wp_get_nav_menu_object($locations['wpdesk-ajax-menu']);
$menu_items = wp_get_nav_menu_items($menu->term_id);
$submenu_items = array();
foreach ($menu_items as $item) {
if ($item->menu_item_parent == $parent_id) {
$submenu_items[] = $item;
}
}
if (empty($submenu_items)) {
wp_send_json_error('No submenu items');
}
$html = '<ul class="sub-menu">';
foreach ($submenu_items as $item) {
$html .= sprintf('<li class="menu-item" data-id="%d"><a href="%s">%s</a></li>', $item->ID, esc_url($item->url), esc_html($item->title));
}
$html .= '</ul>';
wp_send_json_success($html);
}
add_action('wp_ajax_wpdesk_load_submenu', 'wpdesk_ajax_load_submenu');
add_action('wp_ajax_nopriv_wpdesk_load_submenu', 'wpdesk_ajax_load_submenu');Как улучшить и кастомизировать вложенное меню с AJAX
Вы можете дополнительно добавить индикаторы загрузки, анимации раскрытия и обработку ошибок в JavaScript. Также можно кешировать результаты AJAX-запросов на клиенте для ускорения повторных открытий.
Если меню содержит очень много уровней вложенности, стоит подумать о пагинации пунктов или ограничении глубины подгрузки.
Для улучшения SEO можно генерировать базовое меню с первым уровнем пунктов и подгружать остальные динамически, чтобы поисковые системы индексировали хотя бы часть меню.
Использование плагинов для AJAX-меню
Если вам нужно готовое решение, обратите внимание на плагин ABC Pagination, который поддерживает AJAX-пагинацию и может быть адаптирован для меню.
Еще один полезный инструмент — Clearfy Pro, который оптимизирует работу сайта и может помочь с улучшением скорости загрузки меню.
Выводы и рекомендации
Создание вложенного меню с поддержкой AJAX — отличный способ улучшить UX на сайте с большим количеством пунктов. Это снижает нагрузку на сервер и ускоряет отображение контента.
Используйте приведенный пример как основу, адаптируйте его под свои задачи и обязательно тестируйте на реальных данных. Не забывайте про безопасность — проверяйте nonce и sanitize-данные.