Создание динамических меню в WordPress с поддержкой AJAX — задача, которая часто возникает при разработке современных тем и плагинов. Стандартные меню WordPress не всегда подходят для сложных интерфейсов, где нужно подгружать пункты меню без перезагрузки страницы. В этой статье подробно разберём, как реализовать такое меню с помощью AJAX, используя собственные функции, хуки и примеры кода.
Зачем нужны динамические меню с AJAX в WordPress
Статические меню создаются один раз и не меняются без обновления страницы. Однако, если у вас большой сайт с множеством категорий, рубрик или пользовательских типов записей, загружать все пункты сразу неэффективно. Динамические меню позволяют подгружать пункты по мере необходимости, улучшая скорость загрузки и удобство пользователя.
Кроме того, AJAX-меню дают возможность реализовать фильтрацию и сортировку пунктов в реальном времени, без перезагрузки. Это особенно полезно для каталогов, портфолио и магазинов на WooCommerce.
Основные этапы создания динамического меню с AJAX
Для реализации динамического меню нам понадобится:
- Создать HTML-разметку для меню с контейнером, куда будем подгружать пункты.
- Написать JavaScript-код, который будет отправлять AJAX-запросы на сервер при взаимодействии пользователя.
- Реализовать PHP-функцию-обработчик AJAX-запросов, которая будет формировать список пунктов меню и возвращать их в формате JSON или HTML.
- Зарегистрировать AJAX-обработчики в WordPress с помощью хуков
wp_ajax_иwp_ajax_nopriv_. - Обеспечить безопасность и кеширование, если нужно.
Пример: динамическое подгруженное меню категорий с AJAX
1. HTML-разметка меню
Создадим контейнер для меню и кнопку для загрузки дополнительных категорий:
<div id="wpexperts-ajax-menu">
<ul id="wpexperts-menu-list">
<!-- Пункты меню будут подгружаться сюда -->
</ul>
<button id="wpexperts-load-more">Загрузить ещё</button>
</div>2. JavaScript для AJAX-запросов
Добавим скрипт, который при клике на кнопку отправит AJAX-запрос на сервер и подгрузит новые категории:
jQuery(document).ready(function($) {
let page = 1;
$('#wpexperts-load-more').on('click', function() {
page++;
$.ajax({
url: wpexperts_ajax_object.ajax_url,
type: 'POST',
data: {
action: 'wpexperts_load_categories',
page: page
},
success: function(response) {
if(response.success) {
$('#wpexperts-menu-list').append(response.data);
if(!response.has_more) {
$('#wpexperts-load-more').hide();
}
}
}
});
});
});Обратите внимание, что в скрипте используется глобальный объект wpexperts_ajax_object с параметром ajax_url. Его необходимо передать из PHP.
3. PHP: регистрация локализации скрипта и AJAX-обработчика
В файле functions.php вашей темы или в плагине добавим код:
function wpexperts_enqueue_scripts() {
wp_enqueue_script('wpexperts-ajax-menu', get_template_directory_uri() . '/js/wpexperts-ajax-menu.js', array('jquery'), null, true);
wp_localize_script('wpexperts-ajax-menu', 'wpexperts_ajax_object', array(
'ajax_url' => admin_url('admin-ajax.php')
));
}
add_action('wp_enqueue_scripts', 'wpexperts_enqueue_scripts');
function wpexperts_ajax_load_categories() {
$paged = isset($_POST['page']) ? intval($_POST['page']) : 1;
$categories_per_page = 5;
$offset = ($paged - 1) * $categories_per_page;
$args = array(
'taxonomy' => 'category',
'number' => $categories_per_page,
'offset' => $offset,
'hide_empty' => false,
);
$categories = get_terms($args);
if(empty($categories)) {
wp_send_json_success('', 200);
wp_die();
}
$output = '';
foreach($categories as $cat) {
$output .= '<li><a href="' . esc_url(get_category_link($cat->term_id)) . '">' . esc_html($cat->name) . '</a></li>';
}
$total_categories = wp_count_terms('category', array('hide_empty' => false));
$has_more = $offset + $categories_per_page < $total_categories;
wp_send_json_success(array(
'html' => $output,
'has_more' => $has_more
));
wp_die();
}
add_action('wp_ajax_wpexperts_load_categories', 'wpexperts_ajax_load_categories');
add_action('wp_ajax_nopriv_wpexperts_load_categories', 'wpexperts_ajax_load_categories');4. Корректировка JavaScript для обработки ответа
Обновим JS, чтобы использовать HTML из ответа и проверять наличие следующих страниц:
jQuery(document).ready(function($) {
let page = 1;
$('#wpexperts-load-more').on('click', function() {
page++;
$.ajax({
url: wpexperts_ajax_object.ajax_url,
type: 'POST',
data: {
action: 'wpexperts_load_categories',
page: page
},
success: function(response) {
if(response.success) {
$('#wpexperts-menu-list').append(response.data.html);
if(!response.data.has_more) {
$('#wpexperts-load-more').hide();
}
}
}
});
});
});Расширение функционала: фильтрация и поиск по меню
Чтобы сделать меню ещё удобнее, можно добавить поле поиска или фильтра по таксономиям. Это позволит пользователям быстро находить нужные категории или записи. Принцип реализации схож: создаём input, который при вводе текста отправляет AJAX-запрос с параметром поиска. Сервер фильтрует категории по названию и возвращает подходящие пункты.
Для фильтрации используйте аргумент search в функции get_terms():
$args = array(
'taxonomy' => 'category',
'search' => $search_term,
'number' => $categories_per_page,
'offset' => $offset,
'hide_empty' => false,
);В JS добавьте обработчик события ввода в поле и запускайте AJAX с параметром search.
Советы по оптимизации и безопасности
1. Используйте Nonce для защиты AJAX-запросов от CSRF-атак. Добавьте его в локализацию скрипта и проверяйте в PHP:
if ( ! isset($_POST['nonce']) || ! wp_verify_nonce($_POST['nonce'], 'wpexperts_ajax_nonce') ) {
wp_send_json_error('Ошибка безопасности');
wp_die();
}2. Кешируйте результаты на стороне сервера с помощью Transients API, если данные обновляются нечасто.
3. Ограничьте количество загружаемых пунктов, чтобы не перегружать сервер и не ухудшать UX.
Использование плагинов для динамических меню
Если вы хотите готовое решение, можно рассмотреть плагины, например, ABC Pagination — он позволяет динамически подгружать посты и таксономии с пагинацией и AJAX, что можно адаптировать под меню.
Для более сложных интерфейсов с рейтингами и отзывами подойдёт Expert Review, который умеет работать с AJAX-запросами и фильтрами.
Итог
Динамические меню с AJAX — мощный инструмент, который значительно улучшит взаимодействие пользователей с вашим сайтом на WordPress. Реализовать такое меню можно самостоятельно, используя приведённые примеры кода и рекомендации по безопасности. При необходимости можно интегрировать сторонние плагины для расширения функционала.