WordPress как на ладони
Недорогой хостинг для сайтов на WordPress: wordpress.jino.ru

paginate_links() WP 2.1.0

Позволяет создать ссылки пагинации для любых страниц.

Пример того как выглядит планация: « предыдущая 1 … 3 4 5 6 7 … 9 следующая »

Технически функцию можно использовать для создания пагинации где угодно. Эта функция является ядром для всех функций пагинации в WordPress.

Для построения пагинации в WordPress есть также специальные функции (обертки для этой функции):

Немного о параметрах

Параметр 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 );

Использование

<?php echo 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, то в списке ссылок будут показаны все страницы участвующие в пагинации. По умолчанию показывается только несколько ссылок спереди и сзади номера текущей страницы, количество ссылок регулируется параметрами end_size и mid_size.
По умолчанию: false
end_size(число)
Сколько номеров показывать сначала и конца ("предыдущая 12 ... 4 ... 89 следующая").
По умолчанию: 1
mid_size(число)
Сколько номеров показывать до и после текущего номера (... 123 5 678 ...).
По умолчанию: 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/?([\'"])~', '\1', $result );

	echo $result;
}

// Теперь, где нужно вывести пагинацию используем
// my_pagenavi();

#2 Пример с произвольным запросом 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 = new 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
) );
?>

#3 Пагинация для произвольного запроса 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. Потому что c page будет перенаправление со страницы пагинации на саму запись, а с paged будет 404 ошибка на странице пагинации.

  • Для получения номера страницы пагинации вместо привычного get_query_var( 'paged' ) используем get_query_var( 'page' ).

  • Этот код не будет работать на страницах у которых контент делиться на несколько страниц тегом <!--nextpage-->, подробнее см. здесь.

Заметки

  • 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.

Код paginate_links() WP 5.7.2

<?php
function paginate_links( $args = '' ) {
	global $wp_query, $wp_rewrite;

	// Setting up default values based on the current URL.
	$pagenum_link = html_entity_decode( get_pagenum_link() );
	$url_parts    = explode( '?', $pagenum_link );

	// Get max pages and current page out of the current query, if available.
	$total   = isset( $wp_query->max_num_pages ) ? $wp_query->max_num_pages : 1;
	$current = get_query_var( 'paged' ) ? (int) get_query_var( 'paged' ) : 1;

	// Append the format placeholder to the base URL.
	$pagenum_link = trailingslashit( $url_parts[0] ) . '%_%';

	// URL base depends on permalink settings.
	$format  = $wp_rewrite->using_index_permalinks() && ! strpos( $pagenum_link, 'index.php' ) ? 'index.php/' : '';
	$format .= $wp_rewrite->using_permalinks() ? user_trailingslashit( $wp_rewrite->pagination_base . '/%#%', 'paged' ) : '?paged=%#%';

	$defaults = array(
		'base'               => $pagenum_link, // http://example.com/all_posts.php%_% : %_% is replaced by format (below).
		'format'             => $format, // ?page=%#% : %#% is replaced by the page number.
		'total'              => $total,
		'current'            => $current,
		'aria_current'       => 'page',
		'show_all'           => false,
		'prev_next'          => true,
		'prev_text'          => __( '&laquo; Previous' ),
		'next_text'          => __( 'Next &raquo;' ),
		'end_size'           => 1,
		'mid_size'           => 2,
		'type'               => 'plain',
		'add_args'           => array(), // Array of query args to add.
		'add_fragment'       => '',
		'before_page_number' => '',
		'after_page_number'  => '',
	);

	$args = wp_parse_args( $args, $defaults );

	if ( ! is_array( $args['add_args'] ) ) {
		$args['add_args'] = array();
	}

	// Merge additional query vars found in the original URL into 'add_args' array.
	if ( isset( $url_parts[1] ) ) {
		// Find the format argument.
		$format       = explode( '?', str_replace( '%_%', $args['format'], $args['base'] ) );
		$format_query = isset( $format[1] ) ? $format[1] : '';
		wp_parse_str( $format_query, $format_args );

		// Find the query args of the requested URL.
		wp_parse_str( $url_parts[1], $url_query_args );

		// Remove the format argument from the array of query arguments, to avoid overwriting custom format.
		foreach ( $format_args as $format_arg => $format_arg_value ) {
			unset( $url_query_args[ $format_arg ] );
		}

		$args['add_args'] = array_merge( $args['add_args'], urlencode_deep( $url_query_args ) );
	}

	// Who knows what else people pass in $args.
	$total = (int) $args['total'];
	if ( $total < 2 ) {
		return;
	}
	$current  = (int) $args['current'];
	$end_size = (int) $args['end_size']; // Out of bounds? Make it the default.
	if ( $end_size < 1 ) {
		$end_size = 1;
	}
	$mid_size = (int) $args['mid_size'];
	if ( $mid_size < 0 ) {
		$mid_size = 2;
	}

	$add_args   = $args['add_args'];
	$r          = '';
	$page_links = array();
	$dots       = false;

	if ( $args['prev_next'] && $current && 1 < $current ) :
		$link = str_replace( '%_%', 2 == $current ? '' : $args['format'], $args['base'] );
		$link = str_replace( '%#%', $current - 1, $link );
		if ( $add_args ) {
			$link = add_query_arg( $add_args, $link );
		}
		$link .= $args['add_fragment'];

		$page_links[] = sprintf(
			'<a class="prev page-numbers" href="%s">%s</a>',
			/**
			 * Filters the paginated links for the given archive pages.
			 *
			 * @since 3.0.0
			 *
			 * @param string $link The paginated link URL.
			 */
			esc_url( apply_filters( 'paginate_links', $link ) ),
			$args['prev_text']
		);
	endif;

	for ( $n = 1; $n <= $total; $n++ ) :
		if ( $n == $current ) :
			$page_links[] = sprintf(
				'<span aria-current="%s" class="page-numbers current">%s</span>',
				esc_attr( $args['aria_current'] ),
				$args['before_page_number'] . number_format_i18n( $n ) . $args['after_page_number']
			);

			$dots = true;
		else :
			if ( $args['show_all'] || ( $n <= $end_size || ( $current && $n >= $current - $mid_size && $n <= $current + $mid_size ) || $n > $total - $end_size ) ) :
				$link = str_replace( '%_%', 1 == $n ? '' : $args['format'], $args['base'] );
				$link = str_replace( '%#%', $n, $link );
				if ( $add_args ) {
					$link = add_query_arg( $add_args, $link );
				}
				$link .= $args['add_fragment'];

				$page_links[] = sprintf(
					'<a class="page-numbers" href="%s">%s</a>',
					/** This filter is documented in wp-includes/general-template.php */
					esc_url( apply_filters( 'paginate_links', $link ) ),
					$args['before_page_number'] . number_format_i18n( $n ) . $args['after_page_number']
				);

				$dots = true;
			elseif ( $dots && ! $args['show_all'] ) :
				$page_links[] = '<span class="page-numbers dots">' . __( '&hellip;' ) . '</span>';

				$dots = false;
			endif;
		endif;
	endfor;

	if ( $args['prev_next'] && $current && $current < $total ) :
		$link = str_replace( '%_%', $args['format'], $args['base'] );
		$link = str_replace( '%#%', $current + 1, $link );
		if ( $add_args ) {
			$link = add_query_arg( $add_args, $link );
		}
		$link .= $args['add_fragment'];

		$page_links[] = sprintf(
			'<a class="next page-numbers" href="%s">%s</a>',
			/** This filter is documented in wp-includes/general-template.php */
			esc_url( apply_filters( 'paginate_links', $link ) ),
			$args['next_text']
		);
	endif;

	switch ( $args['type'] ) {
		case 'array':
			return $page_links;

		case 'list':
			$r .= "<ul class='page-numbers'>\n\t<li>";
			$r .= implode( "</li>\n\t<li>", $page_links );
			$r .= "</li>\n</ul>\n";
			break;

		default:
			$r = implode( "\n", $page_links );
			break;
	}

	/**
	 * Filters the HTML output of paginated links for archives.
	 *
	 * @since 5.7.0
	 *
	 * @param string $r    HTML output.
	 * @param array  $args An array of arguments. See paginate_links()
	 *                     for information on accepted arguments.
	 */
	$r = apply_filters( 'paginate_links_output', $r, $args );

	return $r;
}

Из раздела: Архивы

43 коммента
Полезные 3 Вопросы 2 Все
    Войти