paginate_links()
Дозволяє створити посилання пагінації для будь-яких сторінок.
Приклад того, як виглядає планація:« предыдущая 1 … 3 4 5 6 7 … 9 следующая »
Технічно функцію можна використовувати для створення пагінації будь-де. Ця функція є ядром для всіх функцій пагінації WordPress.
Для побудови пагінації в WordPress є також спеціальні функції (обгортки для цієї функції):
Ця функція жорстко додає всі $_GET параметри поточного запиту (поточної сторінки) посилання пагінації. Тому, наприклад, якщо вона використовується в обробнику AJAX запиту, всі URL в ній будуть містити поточні GET параметри. Тикет з цієї теми та обговорення нижче в коментарях .
Трохи про параметри
Параметр total
повинен отримати загальну кількість сторінок пагінації, а параметр current
номер поточної сторінки пагінації.
Приклад параметра base
– http://example.com/all_posts.php%_%
, де %_% буде замінено тим, що вказано в параметрі format = '?page=%#%'
, тут %#% буде замінено числом поточної сторінки пагінації.
Взагалі, base
можна відразу вказати наприклад так: http://example.com/all_posts.php?page=%#%
, і при цьому format = ''
(порожньо).
До посилання можна додати змінні запити , для цього вкажіть потрібні змінні та їх значення у вигляді масиву до параметра add_args
. Докладніше див. функцію add_query_arg() .
Щоб додати посилання на попередню/наступну сторінку, потрібно включити логічний параметр prev_next
(вказати йому true ), а потім можна встановити текст посилань, вказавши параметри prev_text / next_text
(попереднє посилання/наступне посилання).
Хуки з функції
Повертає
Строку|Массив|null
.
Шаблон використання
$args = [ 'base' => '%_%', 'format' => '?page=%#%', 'total' => 1, 'current' => 0, 'show_all' => False, 'end_size' => 1, 'mid_size' => 2, 'prev_next' => True, 'prev_text' => __('« Previous'), 'next_text' => __('Next''), 'type' => 'plain', 'add_args' => False, 'add_fragment' => '', 'before_page_number' => '', 'after_page_number' => '' ]; echo paginate_links($args);
Використання
paginate_links($args);
-
$args
(рядок/масив) -
Аргументи для побудови пагінації.
За замовчуванням: попереднє встановлення
Аргументи параметра $args
-
base
(рядок) Базовий формат УРЛ, який буде використаний для створення посилання на пагінацію. Наприклад:
http://example.com/all_posts.php%_%
тут%_%
буде замінено значення аргументу format .Можна
base
відразу вказати наприклад так:http://example.com/all_posts.php?page=%#%
, і при цьому вказати порожній рядок вformat
.За замовчуванням: ‘%_%’
-
format
(рядок) -
Формат заміни.
За замовчуванням: ‘?page=%#%’ -
total
(число) -
Загальна кількість сторінок, що беруть участь у пагінації.
За замовчуванням: 1 -
current
(число) - Номер поточної сторінки пагінації.
-
show_all
(логічний) -
true – будуть показані всі сторінки, що беруть участь у пагінації.
false – (За замовчуванням) відображається лише кілька посилань попереду та позаду номера поточної сторінки. Кількість посилань регулюється параметрами
end_size
та
mid_size
.
Типово: false -
end_size
(число) -
Скільки посилань показати з початку та кінця:
"предыдущая 1 2 ... [4] ... 8 9 следующая"
.
За замовчуванням: 1 -
mid_size
(число) -
Скільки номерів показувати до та після поточного номера:
1 ... 2 3 [4] 5 6 ... 99
.
За замовчуванням: 2 -
prev_next
(логічний) -
Виводити бічні посилання “попередня/наступна сторінка”. За промовчанням виводяться, якщо НЕ потрібно виводити ці посилання пишемо false.
Типово: true -
prev_text
(рядок) -
Текст посилання “Попередня сторінка”.
Типово: __(‘« Previous’) -
next_text
(рядок) -
Текст посилання “Наступна сторінка”.
Типово: __(‘Next »’) -
type
(рядок) Контролює в якому форматі буде повернено результат:
plain
– просто посилання розділені пробілом (За замовчуванням).array
– у вигляді масиву даних для подальшої обробки PHP.list
– <ul> список.
Типово: ‘plain’
-
add_args
(масив) -
Масив змінних запиту, які потрібно додати до посилань пагінації. функцію
add_query_arg() .
За замовчуванням: array() -
add_fragment
(рядок) -
Текст, який додається до всіх посилань.
За замовчуванням: ” -
aria_current
(рядок) (WP 4.9) -
Значення атрибуту
aria-current
. Можливі значення: ‘page’, ‘step’, ‘location’, ‘date’, ‘time’, ‘true’, ‘false’.
Типово: ‘page’ . -
before_page_number
(рядок) - Текст/рядок перед числом пагінації.
-
after_page_number
(рядок) Текст/рядок після числа пагінації.
Параметри before_page_number та after_page_number дозволяють обернути саме число пагінації. Наприклад тег <span> для стилізації.
Взагалі ці параметри були створені для того, щоб вказати текст для роботів, щоб при перегляді коду було зрозуміло для чого призначені посилання.
Приклади
#1 Пагінація, аналог wp_pagenavi
Щоб додати пагінацію на сторінку результатів пошуку або сторінку архівів, використовуйте такий код:
function my_pagenavi() { global $wp_query; $ big = 999999999; // Унікальне число для заміни $ args = array ( 'base' => str_replace( $big, '%#%', get_pagenum_link( $big ) ), 'format' => '', 'current' => max( 1, get_query_var('paged') ), 'total' => $wp_query->max_num_pages, ); $result = paginate_links( $args ); // видаляємо добавку до пагінації для першої сторінки $result = preg_replace( '~/page/1/?(['"])~', '', $result ); echo $result; } // Тепер, де потрібно вивести пагінацію використовуємо // my_pagenavi();
#2 Пагінація для довільного запиту WP_Query
У прикладі нижче будемо виводити продукти WooCommerce (post_type=product) на окремій сторінці запису (post_type=post). Тобто. використовуватимемо довільний запит і зробимо для нього пагінацію.
// Запитуємо продукти $query = New WP_Query([ 'post_type' => 'product', 'posts_per_page' => 5, 'paged' => get_query_var( 'page' ), ]); // Обробляємо отримані у запиті продукти, якщо вони є if ( $query->have_posts() ) { while ( $query->have_posts() ) { $query->the_post(); // виводимо заголовок the_title(); } wp_reset_postdata(); } // Виводимо пагінацію, якщо продуктів більше за запитану кількість echo paginate_links([ 'base' => user_trailingslashit( wp_normalize_path( get_permalink() .'/%#%/' ) ), 'current' => max( 1, get_query_var( 'page' ) ), 'total' => $query->max_num_pages, ]);
Ми вказали виводити по 5 товарів, якщо їх, наприклад 22, буде виведено 5 елементів пагінації, у тому числі 4 будуть посиланнями такого виду:
Поточна сторінка, посилання не виводиться (5 продуктів) http://example.com/назва-запису/2/ (5 продуктів) http://example.com/назва-запису/3/ (5 продуктів) http://example.com/назва-запису/4/ (5 продуктів) http://example.com/назва-запису/5/ (2 продукти)
Зверніть увагу:
У параметрі
base
, де формується вид посилання пагінації, не використовуються такі слова якpage
абоpaged
. Тому що cpage
буде перенаправлення зі сторінки пагінації на сам запис, а зpaged
буде 404 помилка на сторінці пагінації.Для отримання номера сторінки пагінації замість звичного
get_query_var( 'paged' )
використовуємоget_query_var( 'page' )
.- Цей код не буде працювати на сторінках, у яких контент ділитися на кілька сторінок тегом <!–nextpage–> , докладніше див тут .
#3 Альтернатива цієї функції
paginate_links() завжди повертає HTML, навіть якщо параметр type=array
ви отримаєте масив готових <a>
тегів. Це може не підійти, коли потрібно повністю змінити HTML-структуру вашої пагінації. Нижче невелика функція, яка повертає масив об’єктів замість HTML.
/** * Generates array of pagination links. * * @author Kama (wp-kama.com) * @ Varsion 2.5 * * @param array $args { * * @type int $total Maximum allowable pagination page. * @type int $current Current page number. * @type string $url_base URL pattern. Use `{pagenum}` placeholder. * @type string $first_url URL на першу сторінку. Default: '' - така автоматичнавід $url_base. * @type int $mid_size Номер links before/after current: 1 ... 1 2 [3] 4 5 ... 99. Default: 2. * @type int $end_size Число повідомлень на написах: 1 2 ... 3 4 [5] 6 7 ... 98 99. Default: 1. * @type bool $show_all true - Show all links. Default: false. * @type string $a_text_patt `%s` will be replaced with number of pagination page. Default: ``%s'`. * @type bool $is_prev_next Whether to show prev/next links. «Previou 1 2 [3] 4...99 Next». Default: false. * @type string $prev_text Default: `Previous`. * @type string $next_text Default: `Next'. * } * * @return array */ function kama_paginate_links_data( array $args ): array { global $wp_query; $args += [ 'total' => 1, 'current' => 0, 'url_base' => '/{pagenum}', 'first_url' => '', 'mid_size' => 2, 'end_size' => 1, 'show_all' => false, 'a_text_patt' => '%s', 'is_prev_next' => false, 'prev_text' => 'Previous', 'next_text' => 'Next»', ]; $rg = (object) $args; $total_pages = max( 1, (int) ( $rg->total?: $wp_query->max_num_pages ) ); if( $total_pages === 1 ){ return []; } // fix working parameters $rg->total = $total_pages; $rg->current = max( 1, abs( $rg->current ?: get_query_var( 'paged', 1 ) ))); $rg->url_base = $rg->url_base?: str_replace( PHP_INT_MAX, '{pagenum}', get_pagenum_link( PHP_INT_MAX ) ); $rg->url_base = wp_normalize_path( $rg->url_base ); if( ! $rg->first_url ){ // /foo/page(d)/2 >>> /foo/ /foo?page(d)=2 >>> /foo/ $rg->first_url = preg_replace( '~/paged?/{pagenum}/?|[?]paged?={pagenum}|/{pagenum}/?~', '', $rg->url_base ); $rg->first_url = user_trailingslashit( $rg->first_url ); } // core array if( $rg->show_all ){ $active_nums = range( 1, $rg->total ); } else { if( $rg->end_size > 1 ){ $start_nums = range( 1, $rg->end_size ); $end_nums = range( $rg->total - ($rg->end_size - 1), $rg->total); } else { $start_nums = [1]; $end_nums = [ $rg-> total ]; } $from = $rg->current - $rg->mid_size; $to = $rg->current + $rg->mid_size; if( $from < 1 ){ $to = min($rg->total, $to + absint($from)); $ from = 1; } if( $to > $rg->total ){ $ from = max (1, $ from - ($ to - $ rg-> total)); $to = $rg->total; } $active_nums = array_merge( $start_nums, range( $from, $to ), $end_nums ); $active_nums = array_unique($active_nums); $active_nums = array_values( $active_nums ); // reset keys } // fill by core array $pages = []; if( 1 === count( $active_nums ) ){ return $pages; } $item_data = static function( $num ) use ( $rg ){ $ data = [ 'is_current' => false, 'page_num' => null, 'url' => null, 'link_text' => null, 'is_prev_next' => false, 'is_dots' => false, ]; if( 'dots' === $num ){ return (object) [ 'is_dots' => true, 'link_text' => '…', ] + $ data; } $is_prev = 'prev' === $num && ( $num = max( 1, $rg->current - 1 ) ); $is_next = 'next' === $num && ( $num = min( $rg->total, $rg->current + 1 ) ); $ data = [ 'is_current' =>! ( $is_prev || $is_next ) && $num === $rg->current, 'page_num' => $num, 'url' => 1 === $num ? $rg->first_url : str_replace( '{pagenum}', $num, $rg->url_base ), 'is_prev_next' => $is_prev || $is_next, ] + $ data; if($is_prev) { $data['link_text'] = $rg->prev_text; } elseif( $is_next ) { $data['link_text'] = $rg->next_text; } else { $data['link_text'] = sprintf( $rg->a_text_patt, $num); } return (object) $data; }; foreach( $active_nums as $indx => $num ){ $pages[] = $item_data($num); // set dots $next = $active_nums[ $indx + 1 ] ?? null; if( $next && ($num + 1) !== $next ){ $pages[] = $item_data('dots'); } } if( $rg->is_prev_next ){ $rg->current !== 1 && array_unshift( $pages, $item_data( 'prev' ) ); $rg->current !== $rg->total && $pages[] = $item_data( 'next' ); } return $pages; }
Що виводить функція:
$links_data = kama_paginate_links_data([ 'total' => 3, 'current' => 2, 'url_base' => 'http://site.com/page-name/paged/{pagenum}', 'mid_size' => 2, ]); print_r ($ links_data); /* Array ( [0] => stdClass Object ( [is_current] => [page_num] => 288 [url] => https://holder.loc/ua/coins/page/288 [is_prev_next] => 1 [link_text] => « Назад [is_dots] => ) [1] => stdClass Object ( [is_current] => [page_num] => 1 [url] => https://holder.loc/ru/coins/ [is_prev_next] => [link_text] => 1 [is_dots] => ) [2] => stdClass Object ( [is_dots] => 1 [link_text] => … [is_current] => [page_num] => [url] => [is_prev_next] => ) [3] => stdClass Object ( [is_current] => [page_num] => 285 [url] => https://holder.loc/ua/coins/page/285 [is_prev_next] => [link_text] => 285 [is_dots] => ) [4] => stdClass Object ( [is_current] => [page_num] => 286 [url] => https://holder.loc/ua/coins/page/286 [is_prev_next] => [link_text] => 286 [is_dots] => ) [5] => stdClass Object ( [is_current] => 1 [page_num] => 287 [url] => https://holder.loc/ua/coins/page/287 [is_prev_next] => [link_text] => 287 [is_dots] => ) ) */
Тепер використовуємо цю функцію у циклі:
<?php $links_data = kama_paginate_links_data([ 'total' => 3, 'current' => 2, 'url_base' => 'http://site.com/page-name/paged/{pagenum}', ]); if( $links_data ){ ?> <ul> <?php foreach( $links_data as $link ) { ?> <li> <?php if ( $link->is_dots ) { ?> <span><?= $link->link_text ?></span> <?php } elseif ( $link->is_current ) { ?> <strong><?= $link->link_text ?></strong> <?php } else { ?> <a href="<?php esc_attr_e( $link->url ) ?>"><?php _e( $link->link_text ) ?></a> <?php } ?> </li> <?php } ?> </ul> <?php }
Отримаємо:
<ul> <li> <a href="http://site.com/page-name/paged/1">1</a> </li> <li> <strong>2</strong> </li> <li> <a href="http://site.com/page-name/paged/3">3</a> </li> </ul>
#4 Приклад із довільним запитом WP_Query
Коли записи виводяться окремим запитом за допомогою new WP_Query для виведення пагінації, можна встановити параметр total
, в якому вказати властивість WP_Query::$max_num_pages . Розглянемо приклад:
Це лише демонстраційний приклад, тому що він не враховує основного запиту, в якому може виходити 404 сторінка і до цього коду справа взагалі не дійде. Також він може працювати неправильно на окремій сторінці запису.
<?php // 1 значення за замовчуванням $paged = get_query_var('paged')? absint(get_query_var('paged')): 1; $the_query = новий WP_Query( array( 'posts_per_page' => 5, 'category_name' => 'gallery', 'paged' => $paged, ))); // цикл виведення отриманих записів while( $the_query->have_posts() ){ $the_query->the_post(); ?> <!-- HTML кожного запису --> <?php } wp_reset_postdata(); // пагінація для довільного запиту $ big = 999999999; // Унікальне число echo paginate_links( array( 'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ), 'current' => max( 1, get_query_var('paged') ), 'total' => $the_query->max_num_pages ))); ?>
нотатки
- Global. WP_Query. $wp_query WordPress Query object.
- Global. WP_Rewrite. $wp_rewrite WordPress rewrite component.
список змін
З версії 2.1.0 | Введено. |
З версії 4.9.0 | Added the aria_current argument. |