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