WordPress подгрузка постов кнопкой показать еще или бесконечным скроллом

21 сентября 2019 WordPress Ajax
Кнопка «Показать ещё» и бесконечный скроллинг — это по сути постраничная навигация, которая подгружает следующую страницу с постами без перезагрузки страницы. Подобные примеры часто можно встретить в лентах соц. сетей. В этом примере показана реализация кнопки «Показать ещё» и бесконечного скроллинга постов на Ajax в CMS WordPress.
Кнопка «Показать ещё» в WordPress
Принцип использования сводится к тому, что если на странице есть ещё не показанные посты, т.е. следующая страница, то будет выведена кнопка «Показать ещё». При нажатии на неё посылается стандартный Ajax-запрос к обработчику, который отдает посты следующей страницы и они отображаются ниже уже показанных.
Давайте создадим кнопку в списке постов рубрики. Для этого в файле category.php после цикла while, добавляем следующий код:
<?php if ($wp_query->max_num_pages > 1) : ?>
<script>
var ajaxurl = '<?php echo site_url(); ?>/wp-admin/admin-ajax.php';
var posts_vars = '<?php echo serialize($wp_query->query_vars); ?>';
var current_page = <?php echo (get_query_var('paged')) ? get_query_var('paged') : 1; ?>;
var max_pages = '<?php echo $wp_query->max_num_pages; ?>';
</script>
<button id="loadmore">Показать ещё</button>
<?php endif; ?>При первом вызове этот код выводит кнопку, если общее число страниц max_num_pages больше 1. А так же задает нужные JS переменные ajaxurl — ссылка на стандартный обработчик WP, posts_vars — данные запроса, current_page — номер текущей страницы, max_pages — максимальное кол-во страниц.
Теперь необходимо создать JS-скрипт, который отправляет Ajax запросы и выводит посты при нажатии на кнопку. Назовем его loadmore.js и поместим его в папку js текущей темы. Про основы Ajax в WordPress можно почитать в этой статье. JMS University — это каталог онлайн-курсов по профессиям из сферы it и digital, программированию, маркетингу, аналитике, дизайну, менеджменту и Soft Skills https://jms.university/courses/.
jQuery(function($){
$('#loadmore').click(function(){ // клик на кнопку
$(this).text('Загрузка...'); // меняем текст на кнопке
// получаем нужные переменные
var data = {
'action': 'loadmore',
'query': posts_vars,
'page' : current_page
};
// отправляем Ajax запрос
$.ajax({
url:ajaxurl,
data:data,
type:'POST',
success:function(data){
if(data) {
$('#loadmore').text('Показать ещё').before(data); // добавляем новые посты
current_page++; // записываем новый номер страницы
if (current_page == max_pages) $("#loadmore").remove(); // если последняя страница, удаляем кнопку
} else {
$('#loadmore').remove(); // если посты не были получены так же удаляем кнопку
}
}
});
});
});Теперь нужно подключить этот скрипт в теме WordPress. В файле functions.php добавляем следующий код:
function loadmore_script() {
wp_enqueue_script('jquery'); // подключает библиотеку jQuery необходимую для работы скрипта
wp_enqueue_script('loadmore', get_stylesheet_directory_uri() . '/js/loadmore.js', array('jquery')); // подключаем loadmore.js
}
add_action('wp_enqueue_scripts', 'loadmore_script');Ну и последний шаг — это создание PHP функции, которая будет вызываться Ajax-запросом и отдавать нужные посты. Все в том же файле functions.php добавляем код:
function loadmore_get_posts(){
$args = unserialize(stripslashes($_POST['query']));
$args['paged'] = $_POST['page'] + 1; // следующая страница
$args['post_status'] = 'publish';
query_posts($args);
// если посты есть
if(have_posts()) :
while(have_posts()): the_post();
the_post();?>
<h2><?php the_title();?></h2>
<?php the_content();?>
<?php
//get_template_part('content-template');
endwhile;
endif;
die();
}
add_action('wp_ajax_loadmore', 'loadmore_get_posts');
add_action('wp_ajax_nopriv_loadmore', 'loadmore_get_posts');В цикле можно сразу указать HTML-разметку поста или загрузить шаблон из папки темы с помощью функции get_template_part('content-template');. В данном случае будет загружен файл content-template.php из папки текущей темы.
Бесконечный скролл на WordPress
Берём за основу пример с кнопкой «Показать ещё» и немного модернизируем код в файлах category.php и loadmore.js. Остальной код оставляем тот же, что и в примере выше. Так как кнопка больше не нужна, то убираем ее из кода с циклом:
<?php if ($wp_query->max_num_pages > 1) : ?>
<script id="loadmore">
var ajaxurl = '<?php echo site_url() ?>/wp-admin/admin-ajax.php';
var posts_vars = '<?php echo serialize($wp_query->query_vars); ?>';
var current_page = <?php echo (get_query_var('paged')) ? get_query_var('paged') : 1; ?>;
</script>
<?php endif; ?>И изменяем код файла loadmore.js, чтобы он вызывал Ajax-запрос не по нажатию кнопки, а при прокручивании страницы до нижней части сайта.
jQuery(function($){
$(window).scroll(function(){
var bottomOffset = 2000; // отступ от нижней части сайта, достигнув которой будет вызвана подгрузка следующих постов
var data = {
'action': 'loadmore',
'query': posts_vars,
'page' : current_page
};
if($(document).scrollTop() > ($(document).height() - bottomOffset) && !$('body').hasClass('loading')) {
$.ajax({
url:ajaxurl,
data:data,
type:'POST',
beforeSend: function(xhr){
$('body').addClass('loading');
},
success:function(data){
if(data) {
$('#loadmore').before(data);
$('body').removeClass('loading');
current_page++;
}
}
});
}
});
});
Спасибо за простой и понятный код, все сработало
400 Bad Request что делать?
Подскажите, а как вывести из определенной категории?
добавил в функцию loadmore_get_posts() аргумент $args[‘category__in’] = 3; а он выводит пустой блок без данных поста.
У меня после нажатия кнопки выводятся только чётные посты
function loadmore_get_posts(){
$args = unserialize(stripslashes($_POST[‘query’]));
$args[‘paged’] = $_POST[‘page’] + 1; // следующая страница
$args[‘post_status’] = ‘publish’;
// query_posts($args);
$query = new WP_Query( $args );
// если посты есть
if($query->have_posts()) :
while($query->have_posts()): $query->the_post();
$query->the_post();?>
<?php
//get_template_part('content-template');
endwhile;
endif;
die();
}
Добрый день, код сработал, спасибо за понятное описание, у меня есть вопрос один… А как сделать чтобы выводилось допустим по 10 записей и чтобы и четные и нечетные записи выводились? а то сейчас выводится всего 5 записей и только нечетные