Как создать вложенное меню в WordPress с поддержкой AJAX

В современных проектах на 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-данные.

Как создать автоматические уведомления о новых отзывах в WordPress
31.03.2026
Как удалить пустые теги и атрибуты в WordPress: практическое руководство
17.02.2026
WooCommerce: автоматическое удаление неактивных вариантов товаров
17.06.2026
Использование хука WooCommerce 'woocommerce_order_status_changed' для автоматизации
26.04.2026
Как создать собственный виджет в WordPress
13.11.2025

Плагин службы технической поддержки для WordPress. Создание, просмотр и ответ на тикеты. Уведомление пользователей и другие функции.