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

Владислав Белецкий
Владислав Белецкий .
Категория:
Комментариев: 0

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

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

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

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

paginate_links( $args = '' )

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

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

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

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

Если вам нравится это, то вы уже можете спокойно использовать эту функцию для пагинации на страницах блога прямо так 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 по умолчанию равен 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>.

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

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

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

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, чтобы изменить/удалить заголовок пагинации 😁

Подписаться
Уведомить о
guest
0 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии