paginate_links() – как сделать пагинацию WordPress

Помню времена, когда обязательным плагином к установке был WP-Pagenavi, ведь именно благодаря ему на сайтах на WordPress удавалось создать постраничную навигацию.

Постраничная навигация на сайтах WordPress

А по умолчанию это всё выглядело как-то так:

Отсутствие постраничной навигации WordPress
Старая навигация WordPress при помощи функций previous_posts_link() и next_posts_link()

Теперь же, благодаря функции paginate_links() мы можем создавать пагинации без плагина!

Однако несмотря на то, что функция присутствует в ядре WordPress (насколько я знаю, с 2009 года), полное избавление от плагинов из серии WP-Pagenavi произошло уже после появления функций: the_posts_pagination() и get_the_posts_pagination() в 2014-м, хотя обе эти функции работают на основе paginate_links().

paginate_links( $args = '' )

Функция содержит лишь один необязательный параметр $args – массив аргументов, ну а в нём уже свои параметры.

Если в функцию не передавать никаких параметров, то она будет работать только внутри цикла WordPress, обязательно посмотрите мой видеоурок про цикл.

Окей, функция не совсем простая для понимания, поэтому не буду тупо переводить английскую документацию, а опишу принцип её работы. Вы не против? 😁

Пример. HTML пагинации по умолчанию

Прежде всего – функция возвращает вам HTML постраничной навигации, который по умолчанию для страницы блога выглядит так:

HTML постраничной навигации созданной при помощи функции paginate_links()

Если вам нравится это, то вы уже можете спокойно использовать эту функцию для пагинации на страницах блога прямо так echo paginate_links(); и забыть обо всём остальном и не читать дальше пост.

Как изменить ссылки ← Ранее и Далее →

В прошлой главе мы уже окрылились успехом и вывели ссылки пагинации на своей странице блога. Первое, что может захотеться сделать помимо настройки стилей ссылок, это немного подкорректировать ссылки перехода на предыдущую и на следующую страницу.

echo paginate_links(
	array(
		'prev_next' => true,
		'prev_text' => __( '« Previous' ),
		'next_text' => __( 'Next »' ),
	)
);
prev_next
(логическое) отобразить или скрыть ссылки перехода на следующую / предыдущую страницы, укажите false, если хотите их скрыть, так как по умолчанию они отображаются,
prev_text
(строка) текст ссылки перехода на предыдущую страницу,
next_text
(строка) текст ссылки перехода на следующую страницу,

__() – это функция перевода. Подробнее про локализацию в WordPress рекомендую почитать в этом уроке.

Из креативных вариантов перевода я помню встречал что-то подобное:

echo paginate_links(
	array(
		'prev_text' => '← Сюда',
		'next_text' => 'Туда →',
	)
);

Что позволяет преобразить нашу пагинацию в такой вид:

Пагинация с измененным текстом ссылок на предыдущую и следующую страницу

Количество отображаемых ссылок

Есть какое-то определённое количество ссылок которые отображаются до «…» от концов и от центра (текущей страницы), на скриншоте ниже я думаю очень даже понятно, что есть что.

параметры mid_size и end_size пагинации

mid_size по умолчанию равен 2, end_size по умолчанию 1. Если вдруг нас это не устраивает, то в нашей власти это изменить:

echo paginate_links(
	array(
		'mid_size' => 3,
		'end_size' => 2,
	)
);

Формат отображения

Прежде, чем перейти к самому интересному, у нас остаётся ещё несколько дополнительных параметров, которые мы не рассмотрели:

show_all
(логическое) принимает значения true или false (по умолчанию), если установить true, то будут отображаться все ссылки на страницы без добавления «…»,
before_page_number
(строка) текст или HTML код, который добавится перед каждой цифрой в пагинации, ссылки назад и далее не считаются! 😈
after_page_number
(строка) то же самое,что и предыдущий параметр, но только после цифр,
type
(строка) тип отображения, может принимать значения plain (по умолчанию), array – возвращает ссылки в виде массива или же list – в виде маркированного списка <ul>.

Кастомные пагинации для любых целей

Вот мы и перешли к самому интересному. Для того, чтобы сразу же дать вам ясное представление, о чем мы будем тут говорить, я рекомендую взглянуть на этот скриншотец:

Пагинация на странице создания меню WordPress в админке
Сделано при помощи paginate_links() !!

Итак, для того, чтобы создать свою собственную пагинацию для абсолютно чего угодно, мы должны знать кое-то о тех параметрах функции, о которых я пока не упомянул.

base
(строка) то, как выглядт URL нашей страницы пагинации в виде https://misha.agency/all_posts.php%_%, в этой конструкции %_% будет заменён на значение параметра format, то есть например на /page/1 или на ?pg=1 – короче говоря на что угодно, что используется у вас при пагинации в урле. По умолчанию (то есть для страницы блога) берётся значение функции get_pagenum_link(), потом отсекаются все параметры после ? и в конце добавляется %_%,
format
(строка) чтобы будем вкидывать в конец урла для обозначения страниц пагинации, например ?page=%#%. Но и тут есть реплейсмент в виде %#%, который при генерации HTML ссылок будет преобразован во что? В номер страницы конечно же. Параметр не берётся из потолка, а берётся из кода, который у нас выводит цикл с учетом постраничной навигации,
total
(целое) сколько всего страниц у нас получилось,
current
(целое) на какой странице мы находимся в данный момент

Это основные параметры, которые нам понадобятся для создания постраничной, но есть ещё два, которые могут быть вам полезны:

add_fragment
(строка) что добавить в конце каждой ссылки, например #continue-reading
add_args
(массив) параметры урл, которые мы можем накинуть ещё сверху наряду с существующими, например array( 'param1' => 'value1' ).

Но конечно же вся эта теория не имеет никакого смысла без хорошего примера кода. Как вариант давайте замутим пагинацию для произвольного неосновного цикла, написанного на WP_Query.

Во-первых, давайте определимся, на какой странице у нас будет этот дополнительный цикл, что собственно повлияет на значение параметра base, у меня цикл будет на главной, значит base будет site_url() . '%_%'.

Во-вторых, нужно решить, как мы будем обозначать пагинацию в УРЛ сайта. Так как мы сейчас не планируем мутить дополнительных правил в htaccess, и всё должно быть найс энд изи, то я рекомендую использовать для этого обычный параметр в URL, а чтобы потешить моё чсв было легче разобраться, назовём параметр misha. Ссылки тогда будут такие: https://домен/?misha=2 (вторая страница).

Погнали 🚀

// определяем текущую страницу из значения параметра "misha"
$current_page = !empty( $_GET['misha'] ) ? $_GET['misha'] : 1;
 
// обычный WP_Query, ссылка на его документацию чуть выше в тексте
$query = new WP_Query( array(
	'posts_per_page' => 2,
	'paged' => $current_page, // передаём текущую страницу сюда!
) );
 
while( $query->have_posts() ) : $query->the_post();
 
	echo '<h2>' . get_the_title() . '</h2>'; // выведем чисто заголовки для примера
 
endwhile;
 
// я упомянул, что функция ничего не возвращает, если всего только 1 страница постов?
echo paginate_links( array(
	'base' => site_url() . '%_%',
	'format' => '?misha=%#%',
	'total' => $query->max_num_pages,
	'current' => $current_page,
) );
 
wp_reset_postdata(); // чтобы ничего не поломать

У меня этот код заработал идеально ✨

Заключение

Ни разу не ожидал, что получится такой объёмный пост. Но по крайней мере теперь становится ясно, что можно выкинуть в помойку не только плагины постраничной навигации, но и функции the_posts_pagination() и get_the_posts_pagination(), рассудите сами – зачем вам лишняя обёртка функции, которую вам ещё потом придётся хукать через navigation_markup_template, чтобы изменить/удалить заголовок пагинации 😁

Миша

Впервые познакомился с WordPress в 2009 году. Организатор и спикер на конференциях WordCamp. Преподаватель в школах Epic Skills и LoftSchool.

Если вам нужна помощь с сайтом или разработка с нуля на WordPress / WooCommerce — пишите. Я и моя команда будем рады вам помочь!

Комментарии — 7

Комментирование этого поста более не доступно.