В современных проектах на WordPress часто возникает задача динамического обновления контента без перезагрузки страницы. Особенно это актуально для списков постов — например, при реализации пагинации, фильтров или кнопки «Загрузить ещё». В этой статье расскажу, как создать такой обновляемый список постов на AJAX, используя собственный код и минимальное количество плагинов.
Почему стоит использовать AJAX для вывода списка постов
При классической загрузке страницы весь список постов загружается сразу или с помощью пагинации, что требует полной перезагрузки страницы при переключении. Это снижает удобство пользователя и увеличивает нагрузку на сервер.
Использование AJAX позволяет подгружать новые записи динамически, без перезагрузки. Это улучшает UX, снижает трафик и ускоряет взаимодействие.
Кроме того, можно реализовать более сложные фильтры и сортировки, которые будут реагировать на действия пользователя мгновенно.
Основные этапы создания обновляемого списка постов
Реализация состоит из нескольких ключевых шагов:
- Создание базового шаблона вывода постов и HTML-разметки.
- Подключение JavaScript, который будет отправлять AJAX-запросы.
- Создание PHP-функции-обработчика запросов на стороне сервера.
- Регистрация AJAX-обработчика в WordPress.
Разберём каждый шаг подробно.
Создаем базовый шаблон для списка постов
В шаблоне страницы или отдельном файле создаём контейнер для списка и кнопку для подгрузки новых постов:
<div id="wpinc-post-list">
<!-- Здесь выводим первые 5 постов -->
<?php
$args = [
'post_type' => 'post',
'posts_per_page' => 5,
'paged' => 1,
];
$query = new WP_Query($args);
if ($query->have_posts()) {
while ($query->have_posts()) {
$query->the_post();
?>
<article>
<h2><?php the_title(); ?></h2>
<div><?php the_excerpt(); ?></div>
</article>
<?php
}
wp_reset_postdata();
}
?>
</div>
<button id="wpinc-load-more" data-page="1">Загрузить ещё</button>
Здесь мы выводим первые 5 постов и кнопку, которая будет загружать следующие страницы.
Подключаем JavaScript для отправки AJAX-запросов
Далее регистрируем и подключаем скрипт, который будет реагировать на кнопку и делать запросы:
function wpinc_enqueue_scripts() {
wp_enqueue_script('wpinc-ajax-posts', get_template_directory_uri() . '/js/wpinc-ajax-posts.js', ['jquery'], null, true);
wp_localize_script('wpinc-ajax-posts', 'wpinc_ajax_obj', [
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('wpinc_load_more_nonce'),
]);
}
add_action('wp_enqueue_scripts', 'wpinc_enqueue_scripts');
В файле wpinc-ajax-posts.js пишем следующий код:
jQuery(document).ready(function($) {
$('#wpinc-load-more').on('click', function() {
var button = $(this);
var page = parseInt(button.data('page')) + 1;
$.ajax({
url: wpinc_ajax_obj.ajax_url,
type: 'POST',
data: {
action: 'wpinc_load_more',
page: page,
nonce: wpinc_ajax_obj.nonce
},
beforeSend: function() {
button.prop('disabled', true).text('Загрузка...');
},
success: function(response) {
if (response.success) {
$('#wpinc-post-list').append(response.data.html);
button.data('page', page).prop('disabled', false).text('Загрузить ещё');
if (!response.data.has_more) {
button.remove(); // Убираем кнопку, если постов больше нет
}
} else {
button.prop('disabled', false).text('Загрузить ещё');
alert('Ошибка загрузки постов');
}
},
error: function() {
button.prop('disabled', false).text('Загрузить ещё');
alert('Ошибка AJAX-запроса');
}
});
});
});
Этот скрипт отправляет запрос на сервер, передавая номер страницы и nonce для безопасности. При успешном ответе добавляет новые посты в список.
Создаем обработчик AJAX-запроса в PHP
Теперь пишем функцию, которая будет обрабатывать запрос и возвращать HTML новых постов:
function wpinc_ajax_load_more() {
check_ajax_referer('wpinc_load_more_nonce', 'nonce');
$paged = isset($_POST['page']) ? intval($_POST['page']) : 1;
if ($paged < 1) $paged = 1;
$args = [
'post_type' => 'post',
'posts_per_page' => 5,
'paged' => $paged,
];
$query = new WP_Query($args);
if ($query->have_posts()) {
ob_start();
while ($query->have_posts()) {
$query->the_post();
?>
<article>
<h2><?php the_title(); ?></h2>
<div><?php the_excerpt(); ?></div>
</article>
<?php
}
wp_reset_postdata();
$html = ob_get_clean();
wp_send_json_success([
'html' => $html,
'has_more' => ( $paged < $query->max_num_pages ),
]);
} else {
wp_send_json_error('Посты не найдены');
}
wp_die();
}
add_action('wp_ajax_wpinc_load_more', 'wpinc_ajax_load_more');
add_action('wp_ajax_nopriv_wpinc_load_more', 'wpinc_ajax_load_more');
Функция проверяет nonce, получает номер страницы из запроса, выполняет WP_Query и возвращает HTML следующих 5 постов. Также сообщает, есть ли ещё страницы.
Дополнительные советы и оптимизации
Использование кастомных шаблонов для постов
Чтобы не дублировать код вывода постов, можно вынести шаблон в отдельный файл, например, template-parts/content-ajax.php, и подключать его через get_template_part() как на фронте, так и в AJAX-обработчике.
Поддержка фильтров и сортировки
Код легко расширяется: передавайте дополнительные параметры фильтрации из JavaScript и учитывайте их в WP_Query на сервере.
Использование плагинов для упрощения
Если хотите готовое решение, обратите внимание на плагин ABC Pagination от WPShop. Он позволяет настраивать AJAX-пагинацию без кода и гибко управлять выводом.
Итоги
Создание обновляемого списка постов на AJAX в WordPress — задача, которую можно решить своими силами, используя стандартные инструменты WP и минимальный JavaScript. Такой подход улучшит UX и снизит нагрузку на сервер. В статье приведён полный рабочий пример с пояснениями и рекомендациями.