AJAX загрузка постов в WordPress
Рассмотрим, как реализовать кнопку AJAX загрузки постов в WordPress. Т.е. загрузка постов будет осуществляться при нажатии на кнопку «загрузить еще» без перезагрузки страницы.
Содержание:
Подгрузка записей при нажатии на кнопку

Примерный код для страницы шаблона вывода постов.
<?php $posts = new WP_Query(array(
"post_type" => "{тип_записи}", # post, page, custom_post_type
"post_status" => "publish", # статус записи
"posts_per_page" => 6, # кол-во постов вывода/загрузки
"category_name" => "{название_рубрики}", # если рубрика
"tax_query" => array( # если элемент (термин) таксономии
array(
"taxonomy" => "{название_таксономии}", # таксономия
"field" => "slug", # slug/id
"terms" => "{ярлык/id_элемента_таксономии}" # термин (ярлык/id)
)
),
)); ?>
<?php if ($posts->have_posts()) : ?>
<?php while ($posts->have_posts()) : $posts->the_post(); ?>
<?php get_template_part("template-parts/loop-{шаблон}"); ?>
<?php endwhile; ?>
<?php endif; ?>
<?php wp_reset_postdata(); ?>
Теперь добавим кнопку для AJAX подгрузки постов.
<?php // AJAX загрузка постов
if ($posts->max_num_pages > 1) { ?>
<script>
var current_page = 1;
</script>
<button
type="button"
class="btn--load"
data-param-posts='<?= json_encode($posts->query_vars); ?>'
data-max-pages="<?= $posts->max_num_pages; ?>"
data-tpl="portfolio"
>
Загрузить ещё
</button>
<?php } ?>
В JavaScript обработчик передаём:
- current_page — номер текущей страницы;
- data-param-posts — параметры поста (post_type, post_status, posts_per_page и другие);
- data-max-pages — сколько всего страниц;
- data-tpl — тип записи (необходим чтобы на сайте использовать множество кнопок подгрузки записей с одним обработчиком, но разными шаблонами вывода).
JavaScript обработчик
Создадим файл ajax-load-more.js и подключим его в functions.php
jQuery(function ($) {
$(".btn--load").on("click", function () {
const button = $(this);
button.html("Загрузка...");
const data = {
"action": "load_more",
"query": button.data("param-posts"),
"page": current_page,
"tpl": button.data("tpl")
}
$.ajax({
url: "/wp-admin/admin-ajax.php",
data: data,
type: "POST",
success: function (data) {
if (data) {
button.html("Загрузить ещё");
button.prev().prev().append(data);
current_page++;
if (current_page == button.attr("data-max-pages")) {
button.remove();
}
} else {
button.remove();
}
}
});
});
});
Здесь необходимо обратить внимание на button.parent().after(data);
Здесь указываем место, где выводить записи на странице. Используйте перемещение по DOM-дереву:
- prev() — предыдущий элемент,
- next() — следующий,
- parent() — на уровень выше,
- children() — на уровень ниже.
И вставляйте в нужном месте:
- before() — до элемента (рядом),
- after() — после элемента (рядом),
- prepend() — до элемента (внутри)
- append() — после элемента (внутри).
Можете ознакомиться со шпаргалкой jQuery.
Теперь подключим полученный файл ajax-load-more.js в functions.php или же код выше можно просто скопировать в ваш главный файл scripts.js / main.js.
wp_enqueue_script("{название_темы}-load-more", get_template_directory_uri() . "/js/ajax-load-more.js", array("jquery"), "", true );
PHP обработчик
Напишем функцию для AJAX загрузки постов нужного шаблона.
<?php
add_action("wp_ajax_load_more", "load_posts");
add_action("wp_ajax_nopriv_load_more", "load_posts");
function load_posts()
{
$args = json_decode(stripslashes($_POST["query"]), true);
$args["paged"] = $_POST["page"] + 1;
$posts = new WP_Query($args);
$html = '';
if ($posts->have_posts()) : while ($posts->have_posts()) : $posts->the_post();
if ($_POST["tpl"] === "news") {
$html .= get_template_part("template-parts/loop-portfolio");
}
endwhile;
endif;
wp_reset_postdata();
die($html);
}
Для выполнения AJAX запроса /wp-admin/admin-ajax.php, нам необходимо использовать:
- wp_ajax_(action) — для авторизованных пользователей;
- wp_ajax_nopriv_(action) — для НЕ авторизованных.
Чтобы добавить новый параметр (или изменить его), используйте следующий код. Пример.
$args["posts_per_page"] = 3; // по сколько записей подгружать
Чтобы удалить параметр(ы), используйте код:
$args = remove_query_arg(["post_parent"]); // удаление параметра «post_parent»
Теперь необходимо подключить данный файл в functions.php. Назовём его load-posts.php
require get_template_directory() . '/functions/load-posts.php';
«Загрузить ещё» со счётчиком оставшихся записей/страниц в WordPress
В шаблоне вывода постов изменим код после тега script.
<?php
// Получить кол-во постов в определенной категории (типе записи)
$count_posts = wp_count_posts("{тип_записи}"); // post, page, custom_post_type
$published_posts_all = $count_posts->publish; // общее кол-во записей
// ИЛИ
// Получить кол-во постов в определённом термине таксономии
$terms = get_terms(array(
"taxonomy" => "{название_таксономии}", // таксономия
"slug" => "{термин_таксономии}" // элемент таксономии
));
foreach ($terms as $terms) {
$count_posts = $terms->count; // получаем сколько всего постов
}
$published_posts_remain = $count_posts - 10; // оставшееся кол-во записей
?>
<button>
Загрузить ещё
<span><?= $published_posts_remain; ?></span> из
<span><?= $published_posts_all; ?></span>
</button>
AJAX загрузка постов с множеством кнопок
Может встретиться такая задача: у нас в разных вкладках выводятся записи для разных категорий (таксномий).
Т.е. в первой вкладке — записи из «категории 1», во второй — записи из «категории 2» и так далее.
Соответственно у нас будет множество кнопок подгрузки записей.
Предлагаю свой вариант решения данной задачи. Код шаблона будет выглядеть примерно так:
<?php $tax_terms = get_terms("portfolio_category") ?>
<?php if ($tax_terms) : $i = 1; ?>
<ul>
<?php foreach ($tax_terms as $term) : ?>
<li>
<button <?= $i == '1' ? "class=\"active\"" : "" ?> href="#tab-<?= $i ?>">
<?= $term->name ?>
</button>
</li>
<?php $i++;
endforeach; ?>
</ul>
<?php endif; ?>
<?php if ($tax_terms) : $j = 1; ?>
<?php foreach ($tax_terms as $term) : ?>
<?php $posts = new WP_Query(array(
"post_type" => "portfolio",
"post_status" => "publish",
"posts_per_page" => 3,
"tax_query" => array(
array(
"taxonomy" => $term->taxonomy,
"field" => "slug",
"terms" => $term->slug
)
),
)); ?>
<div id="tab-<?= $j ?>" <?= $j == '1' ? "style=\"display:block;\"" : "style=\"display:none;\"" ?>>
<div class="portfolio-item">
<?php if ($posts->have_posts()) :
while ($posts->have_posts()) : $posts->the_post();
get_template_part("template-parts/loop-portfolio");
endwhile;
endif;
wp_reset_postdata(); ?>
</div>
<?php if ($posts->max_num_pages > 1) { ?>
<script>
window['this_page_<?= $j ?>'] = 1;
</script>
<button
class="btn--load"
type="button"
data-param-posts='<?= json_encode($posts->query_vars); ?>'
data-max-pages="<?= $posts->max_num_pages; ?>"
data-tpl="portfolio"
data-num="<?= $j ?>"
>
Больше
</button>
<?php } ?>
</div>
<?php $j++;
endforeach; ?>
<?php endif; ?>
Тогда JavaScript будет выглядеть примерно так:
jQuery(function ($) {
$(".btn--load").on("click", function () {
const button = $(this);
const num = button.attr("data-num");
button.html("Загрузка...");
const data = {
"action": "load_more",
"query": button.attr("data-param-posts"),
"page": window['this_page_' + num],
"tpl": button.data("tpl")
}
$.ajax({
url: "/wp-admin/admin-ajax.php",
data: data,
type: "POST",
success: function (data) {
if (data) {
button.html("Загрузить ещё");
button.prev().prev().append(data);
window['this_page_' + num]++;
if (window['this_page_' + num] == button.attr("data-max-pages")) {
button.remove();
}
} else {
button.remove();
}
}
});
});
});
Если вы знаете более элегантный способ решить данную задачу, то поделитесь им в комментариях.
AJAX загрузка постов при скролле
Вместо кнопки напишем следующий код:
<?php if ($posts->max_num_pages > 1) { ?>
<script>
var current_page = 1;
var param_posts = '<?= json_encode($posts->query_vars); ?>';
var max_pages = '<?= $posts->max_num_pages; ?>';
</script>
<?php } ?>
Заменим JavaScript:
jQuery(function ($) {
const bottom_offset = 3000; // расстояние (в px)
let can_be_loaded = true;
$(window).scroll(function () {
const data = {
'action': 'load_posts',
'query': param_posts,
'page': current_page
};
if ($(document).scrollTop() > ($(document).height() - bottom_offset) && can_be_loaded == true) {
$.ajax({
url: "/wp-admin/admin-ajax.php",
data: data,
type: 'POST',
beforeSend: function (xhr) {
can_be_loaded = false;
},
success: function (data) {
if (data) {
$('.grid').find('.grid__item:last-of-type').after(data); // где вставить
current_page++;
can_be_loaded = true;
if (current_page == max_pages) {
can_be_loaded = false;
}
}
}
});
}
});
});
На этом всё. Если вам понравилась данная статья или же было что-то непонятно, то рекомендую к прочтению:
- Шпаргалка по WordPress.
- Полезные хуки по работе с WordPress.
- Работа с плагином Advanced Custom Fileds (ACF).
Надеюсь, вам понравилась данная информация. Если вам интересна тема web-разработки, то можете следить за выходом новых статей в Telegram.
Поделиться с друзьями:
Статьи из данной категории:
Комментарии (16)
- Федор
- Дмитрий
- миха
- Евгений
- Only to top
- Богдан
- Only to top
- Павел
- Денис
- Only to top
- Егор
- Only to top
- Богдан
- Only to top
- Константин
- Артур