paginate_links() – функция для создания пагинаций

Помню времена, когда обязательным плагином к установке был 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 – массив аргументов, ну а в нём уже свои параметры.

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

1-й момент понимания

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

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

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

2-й момент понимания. Ссылки ← Ранее и Далее →

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

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' => 'Туда →',
	)
);

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

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

3-й момент понимания. Количество отображаемых ссылок.

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

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

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

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

4-й момент понимания. Формат отображения.

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

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

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

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

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

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

base
(строка) то, как выглядт URL нашей страницы пагинации в виде https://misha.blog/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, чтобы изменить/удалить заголовок пагинации 😁

Миша

В последние годы я долго не знал, что мне делать с сайтом misha.blog, ведь он практически не приносит никакого профита, но недавно я осознал, что моя миссия – способствовать распространению WordPress. Ведь WordPress – это лучший движок для разработки сайтов – как для тех, кто готов использовать заложенную структуру этой CMS, так и для тех, кто предпочитает headless решения.

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

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

Комментарии 4

  • Илона 30 января 2020 #

    Добрый день. А можно ли кнопки вперед, назад добавлять не по бокам нумерации, а в конце? Что-то вроде 1,2,3,...,4, Назад, Вперед,

    • Миша 2 февраля 2020 #

      Добрый день Илона,

      я думаю вы можете это сделать легче всего при помощи position:absolute;.

  • Александр 6 февраля 2020 #

    Добрый день, как можно не скрывать ссылки на предыдущую/следующую страницу (находясь на первой или последней странице) ?

    • Миша 7 февраля 2020 #

      Добрый день!

      То есть, находясь на первой странице, всё равно отображать ссылку на предыдущую? Не пробовал такого 🤷‍♂️🙃

Оставить комментарий

Если вы хотите добавить код, не забудьте обернуть его в <pre lang="php"></pre>, в случае несоблюдения этого условия в 99% случаях ваш коммент будет удалён, а автор заблокирован. Печалька.