Пагинация не работает
Я использовал один и тот же код пагинации для большинства созданных мной сайтов. В этот раз он почему-то не работает. Я использовал ссылки для устранения неполадок пагинации здесь, но ничего не помогает. Ниже я прикрепил свой код.
В этот раз я вывожу записи в таблице, и думаю, что это может быть связано с этим, хотя я пробовал выводить и без таблицы - все равно не работает. Вот мой код:
Новый запрос
<?php
$args = array(
'post_type' => 'custom_post_type',
'posts_per_page' => 5,
'paged' => ( get_query_var('paged') ? get_query_var('paged') : 1),
);
query_posts($args);
?>
Таблица с данными из моих пользовательских мета-полей:
<table>
<thead>
<tr>
<th>заголовок</th>
<th>заголовок</th>
<th>заголовок</th>
<th>заголовок</th>
</tr>
</thead>
<tbody>
<?php while (have_posts()) : the_post();?>
<tr>
<td><?php echo get_post_meta($post->ID, 'metakey', true); ?></td>
<td><?php echo get_post_meta($post->ID, 'metakey', true); ?></td>
<td><?php echo get_post_meta($post->ID, 'metakey', true); ?></td>
<td><?php echo get_post_meta($post->ID, 'metakey', true); ?></td>
</tr>
<?php
endwhile;
?>
</tbody>
</table>
Мои ссылки пагинации
<?php
global $wp_query;
$big = 999999999; // нужно невероятно большое число
echo paginate_links( array(
'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
'format' => '?paged=%#%',
'prev_text' => __('Предыдущая'),
'next_text' => __('Следующая'),
'current' => max( 1, get_query_var('paged') ),
'total' => $wp_query->max_num_pages
) );
?>
Когда я говорю, что пагинация не работает, я имею в виду, что ссылки пагинации отображаются с правильным количеством страниц, но при нажатии на вторую страницу ничего не меняется. Пермалинки правильные, отображается domain/page/2
, но страница остается такой же, как и первая. Это происходит на шаблоне страницы, который я создал как home-page.php
. Буду признателен за предложения.

Как я уже упоминал в комментариях, вам никогда не следует использовать query_posts
, используйте query_posts
только если вы намеренно хотите сломать функциональность вашей страницы. Добавьте query_posts
в самый верх вашего СПИСКА ЗЛА.
query_posts
ломает основной объект запроса, тот самый объект, на который полагается ваша функция пагинации. Ваша функция пагинации использует свойство $max_num_pages
из основного запроса. Это лишь одна из многих вещей, которые ломает query_posts
.
Для решения вашей проблемы используйте WP_Query
, так как похоже, что вы используете здесь пользовательский шаблон страницы. Одно замечание: если home-page.php
— это статическая главная страница (что я подозреваю по названию шаблона), тогда
'paged' => ( get_query_var('paged') ? get_query_var('paged') : 1),
должно быть
'paged' => ( get_query_var('page') ? get_query_var('page') : 1),
поскольку статические главные страницы используют page
, а не paged
.
Вы можете попробовать что-то вроде этого: (Очень важно: это не тестировалось и скопировано из вопроса, и всегда помните о сбросе postdata после завершения работы с пользовательским запросом)
<?php
$args = array(
'post_type' => 'custom_post_type',
'posts_per_page' => 5,
'paged' => ( get_query_var('paged') ? get_query_var('paged') : 1),
);
$query = new WP_Query($args);
?>
<table>
<thead >
<tr>
<th>заголовок</th>
<th>заголовок</th>
<th>заголовок</th>
<th>заголовок</th>
</tr>
</thead>
<tbody>
<?php while ($query->have_posts()) : $query->the_post();?>
<tr>
<td><?php echo get_post_meta($post->ID, 'metakey', true); ?></td>
<td><?php echo get_post_meta($post->ID, 'metakey', true); ?></td>
<td><?php echo get_post_meta($post->ID, 'metakey', true); ?></td>
<td><?php echo get_post_meta($post->ID, 'metakey', true); ?></td>
</tr>
<?php
endwhile;
wp_reset_postdata();
?>
</tbody>
</table>
Затем вам просто нужно обновить вашу функцию пагинации, используя свойство $max_num_pages
из вашего пользовательского запроса:
<?php
$big = 999999999; // нужно очень большое число
echo paginate_links( array(
'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
'format' => '?paged=%#%',
'prev_text' => __(' Назад'),
'next_text' => __('Вперед '),
'current' => max( 1, get_query_var('paged') ),
'total' => $query->max_num_pages
) );
?>

Я использовал пользовательский запрос и мне нужно было добавить пагинацию для результатов запроса. Поскольку оригинальная функция paginate_links()
тесно связана с глобальными контекстами $wp_query
и $wp_rewrite
, я адаптировал её для полностью независимой работы. Пример использования:
function myPaginateLinks( WP_Query $wp_query, $args = '' ) {
global $wp_rewrite;
// Установка значений по умолчанию на основе текущего URL.
$pagenum_link = html_entity_decode( get_pagenum_link() );
$url_parts = explode( '?', $pagenum_link );
// Получение общего числа страниц и текущей страницы из запроса, если доступно.
$total = isset( $wp_query->max_num_pages ) ? $wp_query->max_num_pages : 1;
$current = !empty($_GET['pg']) ? absint($_GET['pg']) : 1;
// Добавление плейсхолдера формата к базовому URL.
$pagenum_link = trailingslashit( $url_parts[0] ) . '%_%';
// База URL зависит от настроек постоянных ссылок.
$format = $wp_rewrite->using_index_permalinks() && ! strpos( $pagenum_link, 'index.php' ) ? 'index.php/' : '';
$format .= '?pg=%#%';
$defaults = array(
'base' => $pagenum_link, // http://example.com/all_posts.php%_% : %_% заменяется на format (ниже).
'format' => $format, // ?page=%#% : %#% заменяется на номер страницы.
'total' => $total,
'current' => $current,
'aria_current' => 'page',
'show_all' => false,
'prev_next' => true,
'prev_text' => __( '« Назад' ),
'next_text' => __( 'Вперёд »' ),
'end_size' => 1,
'mid_size' => 2,
'type' => 'plain',
'add_args' => array(), // Массив дополнительных аргументов запроса.
'add_fragment' => '',
'before_page_number' => '',
'after_page_number' => '',
);
$args = wp_parse_args( $args, $defaults );
if ( ! is_array( $args['add_args'] ) ) {
$args['add_args'] = array();
}
// Объединение дополнительных параметров запроса из оригинального URL с массивом 'add_args'.
if ( isset( $url_parts[1] ) ) {
// Находим аргумент формата.
$format = explode( '?', str_replace( '%_%', $args['format'], $args['base'] ) );
$format_query = isset( $format[1] ) ? $format[1] : '';
wp_parse_str( $format_query, $format_args );
// Находим аргументы запроса из запрошенного URL.
wp_parse_str( $url_parts[1], $url_query_args );
// Удаляем аргумент формата из массива аргументов запроса, чтобы избежать перезаписи пользовательского формата.
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 ) );
}
// Кто знает, что ещё могут передать в $args.
$total = (int) $args['total'];
if ( $total < 2 ) {
return;
}
$current = (int) $args['current'];
$end_size = (int) $args['end_size']; // Вне границ? Устанавливаем значение по умолчанию.
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>',
/**
* Фильтр для пагинированных ссылок архивных страниц.
*
* @since 3.0.0
*
* @param string $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>',
/** Этот фильтр документирован в 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">' . __( '…' ) . '</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>',
/** Этот фильтр документирован в 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;
}
/**
* Фильтр для HTML вывода пагинированных ссылок архивов.
*
* @since 5.7.0
*
* @param string $r HTML вывод.
* @param array $args Массив аргументов. Смотрите paginate_links()
* для информации о принимаемых аргументах.
*/
$r = apply_filters( 'paginate_links_output', $r, $args );
return $r;
}
Пример использования:
$myQuery = new WP_Query();
$cars = $myQuery->query([
'post_type' => 'cars',
'paged' => !empty($_GET['pg']) ? absint($_GET['pg']) : 1,
]);
foreach ($cars as $car) {
echo $car->post_title;
}
echo myPaginateLinks($myQuery);
Что даёт точно такой же результат, как и paginate_links, но без привязки к глобальному запросу или правилам перезаписи:
Обратите внимание, что я использую $_GET['pg']
вместо ?paged
для пагинации, так как не хотел, чтобы "магия перезаписи" мешала работе пагинации.
