Загрузка постов. Пагинация
Урок 4
В этом уроке я расскажу вам не только, как создать кнопку «Загрузить ещё» для постов на главной и в категориях, но мы также рассмотрим, как сделать загрузку постов при скролле и при этом сохраним пагинацию для SEO.
Чтобы скачать готовый код из этого урока, вам нужно купить курс.
Вот пример того, что у нас получится в ходе этого урока:
Работать будем со стандартной темой TwentyTwentyOne, во-первых, эта тема довольно простая и будет нетрудно разобраться в коде, во-вторых, вы всегда можете установить её прямо из админки из репозитория тем WordPress.
Что мы попробуем сделать в этом посту?
Для начала нам надо найти файл, в котором добавляется постраничная навигация. В TwentyTwentyOne это два файла – index.php
для главной страницы сайта, где выводятся посты блога и archive.php
– для меток и рубрик.. Если вы не понимаете, в каком файле надо искать в вашей теме, рекомендую взглянуть на этот туториал.
Если же вы решили использовать какую-то из стандартных тем (как я), то напоминаю, что для изменений желательно использовать дочерние темы (это же я и делаю в видео).
Найдите соответствующее место в шаблоне за пределами цикла while
, то есть после того, как заканчивается вывод постов (в TwentyTwentyOne это место практически сразу после endwhile
) и вставляем туда код:
<div id="loadmore" style="text-align:center;"><a href="#" class="button">Загрузить ещё</a></div>
Понятно, нам нужно учесть некоторые моменты, чтобы кнопка отображалась корректно, а именно:
Настройки > Чтение,
то кнопку не отображаем также.Это решается следующими условиями:
global $wp_query; // текущая страница $paged = get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1; // максимум страниц $max_pages = $wp_query->max_num_pages; // если текущая страница меньше, чем максимум страниц, то выводим кнопку if( $paged < $max_pages ) { // тут выводим кнопку }
Кроме того, я предлагаю добавить на кнопку data-атрибут, чтобы передавать в обработчик информацию о том, на какой странице мы находимся в данный момент и какую страницу нужно загрузить.
global $wp_query; // текущая страница $paged = get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1; // максимум страниц $max_pages = $wp_query->max_num_pages; // если текущая страница меньше, чем максимум страниц, то выводим кнопку if( $paged < $max_pages ) { echo '<div id="loadmore" style="text-align:center;"> <a href="#" data-max_pages="' . $max_pages . '" data-paged="' . $paged . '" class="button">Загрузить ещё</a> </div>'; }
Также на кнопку я добавил класс .button
, который стилизует её для темы TwentyTwentyOne.
Успешным выполнением первого шага будет считаться вот такая кнопка, которая должна будет появиться на странице всех ваших записей, но имейте ввиду, что если записей недостаточно для двух страниц, то кнопки не будет, для этого либо создайте больше записей, либо перейдите в Настройки > Чтение
и измените количество отображаемых на странице записей там.
Самый легкий шаг позади.
Документация функций wp_enqueue_script() и get_stylesheet_directory_uri() в помощь. Про подключение скриптов я писал часто и подробно, поэтому сейчас на этом останавливаться не будем, если есть проблемы — смотрите документацию. А этот код — в functions.php
дочерней темы.
add_action( 'wp_enqueue_scripts', 'true_loadmore_scripts' ); function true_loadmore_scripts() { wp_enqueue_script( 'jquery' ); // в TwentyTwentyOne он не подключен по умолчанию wp_enqueue_script( 'true_loadmore', get_stylesheet_directory_uri() . '/loadmore.js', array( 'jquery' ), time() // не кэшируем файл, убираем эту строчку после завершение разработки ); }
Также нам понадобится передать в loadmore.js
динамический адрес обработчика AJAX в WordPress, поэтому мы немного модифицируем наш код, добавив в него функцию wp_localize_script().
add_action( 'wp_enqueue_scripts', 'true_loadmore_scripts' ); function true_loadmore_scripts() { wp_enqueue_script( 'jquery' ); // в TwentyTwentyOne он не подключен по умолчанию wp_register_script( 'true_loadmore', get_stylesheet_directory_uri() . '/loadmore.js', array( 'jquery' ), time() // не кэшируем файл, убираем эту строчку после завершение разработки ); wp_localize_script( 'true_loadmore', 'misha', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) ); wp_enqueue_script( 'true_loadmore' ); }
Вы ещё не создали файл loadmore.js
в папке с темой? Давайте создадим его и добавим туда следующий код:
jQuery(function($){ // определяем в переменные кнопку, текущую страницу и максимальное кол-во страниц var button = $( '#loadmore a' ), paged = button.data( 'paged' ), maxPages = button.data( 'max_pages' ); button.click( function( event ) { event.preventDefault(); // предотвращаем клик по ссылке $.ajax({ type : 'POST', url : misha.ajax_url, // получаем из wp_localize_script() data : { paged : paged, // номер текущей страниц action : 'loadmore' // экшен для wp_ajax_ и wp_ajax_nopriv_ }, beforeSend : function( xhr ) { button.text( 'Загружаем...' ); }, success : function( data ){ paged++; // инкремент номера страницы button.parent().before( data ); button.text( 'Загрузить ещё' ); // если последняя страница, то удаляем кнопку if( paged == maxPages ) { button.remove(); } } }); } ); });
Я постарался сделать этот код максимально простым, дополнительными переменными усложнять его не стал. Если вы хотя бы немного разбираетесь в jQuery, то у вас не возникнет с ним никаких проблем. Даже если не разбираетесь, но сделаете всё по инструкции, то всё тоже будет ок.
Этот код также отправляется в файл functions.php
. Если он вам непонятен, читайте подробнее про циклы, WP_Query и query_posts().
add_action( 'wp_ajax_loadmore', 'true_loadmore' ); add_action( 'wp_ajax_nopriv_loadmore', 'true_loadmore' ); function true_loadmore() { $paged = ! empty( $_POST[ 'paged' ] ) ? $_POST[ 'paged' ] : 1; $paged++; $args = array( 'paged' => $paged, 'post_status' => 'publish' ); query_posts( $args ); while( have_posts() ) : the_post(); get_template_part( 'template-parts/content/content', get_theme_mod( 'display_excerpt_or_full_post', 'excerpt' ) ); endwhile; die; }
Суть в том, что вы просто скроллите страницу вниз, а новые посты подгружаются по мере её прокрутки. Насколько я помню, впервые такая штука появилась у твиттера (могу ошибаться, поправьте, если я не прав), а потом уже все стянули её оттуда.
Скажу честно — заразная вещь. Те, кто сидят на сайте вконтакте, понимают это прекрасно. Так что, если у вас новостной сайт, тогда этот способ загрузки постов просто «must have».
Если вы сделали все предыдущие шаги из поста и дошли до этого момента — тогда отлично, добавим некоторые изменения для шагов 1 и 3.
Содержимое файла loadmore.js
изменится и будет следующим:
jQuery(function($){ $(window).scroll(function(){ var bottomOffset = 2000, // отступ от нижней границы сайта, до которого должен доскроллить пользователь, чтобы подгрузились новые посты button = $( '#loadmore a' ), paged = button.data( 'paged' ), maxPages = button.data( 'max_pages' ); if( $(document).scrollTop() > ($(document).height() - bottomOffset) && !$('body').hasClass('loading')){ $.ajax({ type : 'POST', url : misha.ajax_url, data : { paged : paged, action : 'loadmore' }, beforeSend: function( xhr){ $('body').addClass('loading'); }, success:function(data){ if( data ) { paged++; button.parent().before( data ); $('body').removeClass('loading'); } } }); } }); });
Надеюсь, что не запутал вас. Если возникнут трудности то не забывайте про видео.
Очень многие из моих учеников сталкиваются с тем, что им надо сохранить пагинацию. То есть, чтобы были и кнопка «Загрузить ещё» и пагинация ссылками. Причём сама пагинация должна динамически изменяться в зависимости от того, какие посты подгружены и на какой странице мы находимся после этого.
Пагинация подробно рассмотрена на видеоуроке 🙂