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 записей и только нечетные