Вопрос или проблема
У меня есть настраиваемый тип записи “show”, и в рамках этого типа записи я настроил таксономию / категорию под названием “venue”, которая имеет два варианта “venue-one” и “venue-two” (слуги). На двух архивных страницах, которые я настроил, где каждая показывает все записи из “venue-one” или “venue-two”, пагинация не работает после 3-й страницы. Я использую нумерованную пагинацию, и визуально она отображает корректное количество страниц (учитывая, сколько записей на странице я установил), однако, если кликнуть по странице, начиная с “3”, появляется ошибка 404.
Что я пробовал и не сработало:
- сбросить постоянные ссылки
- изменить максимальное количество записей на странице напрямую через панель управления WP
- убрать мой пользовательский запрос и использовать pre_get_posts (примечание: все мои исследования указывают на то, что это путь к решению моей проблемы, так что я предполагаю, что это может работать, и я просто неправильно кодирую функцию в functions.php или иначе). Если использование pre_get_posts в functions.php действительно является решением, нужно ли мне добавлять что-то новое в файлы шаблонов проблемных архивных страниц, кроме стандартного цикла wp? (и, конечно, убрать пользовательский запрос).
Повторюсь, всё работает идеально, кроме того, что пагинация после 3-й страницы выдаёт 404.
Последнее примечание, пагинация отлично работает на архивной странице для этого типа записи в целом. Проблема возникает только на архивных страницах “venue-one” и “venue-two”.
WP_Query
<?php
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$today = current_time('Ymd');
$args = array (
'post_type' => 'show',
'posts_per_page' => 3,
'paged' => $paged,
'meta_key' => 'show_date',
'order' => 'ASC',
'orderby' => 'meta_value',
'tax_query' => array(
array(
'taxonomy' => 'venue',
'field' => 'slug',
'terms' => 'venue-one'
)
),
'meta_query' => array(
array(
'key' => 'show_date',
'compare' => '>=',
'value' => $today
),
),
);
$the_query = new WP_Query($args);
?>
Цикл
<?php if ($the_query->have_posts() ): while ($the_query->have_posts() ) :$the_query->the_post(); $fields = (object) get_fields(); ?>
Функция пагинации (в functions.php)
function pagination_bar_venue( $custom_query ) {
$total_pages = $custom_query->max_num_pages;
$big = 999999999; // нужно использовать необычное число
if ($total_pages > 1){
$current_page = max(1, get_query_var('paged'));
echo paginate_links(array(
'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
'format' => '?paged=%#%',
'current' => $current_page,
'total' => $total_pages,
));
}
}
Вызов пагинации в шаблоне
<div class="pagination-shows">
<?php pagination_bar_venue($the_query); ?>
</div>
РЕДАКТИРОВАНИЕ + ХОРОШИЕ НОВОСТИ
Всё заработало с функцией pre_get_posts ниже, но…ссылки пагинации теперь не отображаются под постами. Чтобы было ясно, нижеприведённый код работал, и теперь я вижу записи за пределами 3-й страницы (до любой страницы, на которой есть записи, всё работает идеально, если ввести URL). Однако после внедрения, ссылки для перехода по номерам страниц исчезли. Как я могу передать переменную $paged в нижеупомянутое, чтобы они снова отображались? или есть другая проблема?
// получение записей по таксономии
function get_tax_posts( $query ) {
// Убедитесь, что это выполняется только тогда, когда это необходимо
if( !is_admin() && $query->is_main_query() && $query->is_tax('venue')) {
// В этом случае измените параметры сортировки
$query->set('post_type', 'show' );
$query->set('posts_per_page', '3' );
$query->set( 'meta_key', 'show_date' );
$query->set( 'order', 'ASC' );
$query->set( 'orderby', 'meta_value' );
$meta_query[] = array(
array(
'key' => 'show_date',
'value' => current_time('Ymd'),
'compare' => '>=',
),
);
$query->set('meta_query',array( $meta_query ) );
$taxquery = array(
array(
'taxonomy' => 'venue',
'field' => 'slug',
'terms' => 'venue-one',
)
);
$query->set( 'tax_query', $taxquery );
}
}
add_action('pre_get_posts', 'get_tax_posts', 9999);
Теперь пагинация исправлена, но заметил другую проблему. Что касается пагинации, я заменил следующее:
<?php pagination_bar_venue($the_query);?>
На:
<?php the_posts_pagination();?>
и теперь пагинация тоже работает.
Новая проблема заключается в порядке вызова хуков, как я полагаю. Как было указано выше, я имею (2) таксономии для этого, поэтому я сделал 2 отдельные функции в functions php, одну для venue-one (код выше) и другую для venue-two (с другим именем функции, конечно). Похоже, обе одновременно не работают. Работает только та, у которой больший приоритет вызова. Есть ли исправление для этого? спасибо
РЕДАКТИРОВАНИЕ – я думаю, проблема была в том, что имена моих функций были слишком похожи, они не были идентичны, но были похожи, за исключением нескольких букв. Я изменил их так, чтобы они не были похожи вообще, и теперь все, кажется, работает!
У меня была похожая проблема, и это может быть полезно, когда пагинация работает только иногда: например, /page/1/ и /page/2/ работают, а /page/3/ нет. Результат: Ошибка 404. Проблема в том, что значение по умолчанию (12 элементов на странице) для posts_per_page (настройки WordPress/Чтение) всегда загружается из базы данных до загрузки шаблона. Таким образом, $args=[‘posts_per_page’ => 1] в кастомной записи WP_Query($args) влияет на пагинацию и количество загруженных элементов, но не на правило перезаписи paged!
Предлагаемое решение – добавить pre_get_posts() в function.php и разделить по кастомному пост_типу. Пример:
//Добавьте в functions.php, так как он должен загружаться до загрузки шаблона
function hwl_home_pagesize( $query ) {
if ( get_post_type() == "your_custom_post_type" )
$query->query_vars['posts_per_page'] = 2; //такое же, как в WP_Query arg или добавить в WP_Query arg get_option('posts_per_page')
}
add_action('pre_get_posts', 'hwl_home_pagesize', 1);
см. также: https://core.trac.wordpress.org/ticket/22299 (На мой взгляд, это все еще проблема архитектуры, независимо от того, что уже было сказано 9 лет назад.)
.
Ответ или решение
Для специалистов в области информационных технологий часто возникают вопросы, связанного с исправлением ошибок на сайте WordPress. Одна из таких проблем касается пагинации на страницах архивов категории, когда она работает корректно только до третьей страницы, а на последующих страницах появляется ошибка 404. В данном случае проблема наблюдается на страницах архивов пользовательского типа записей "show", в которых используется таксономия/категория "venue" с двумя вариантами: "venue-one" и "venue-two". Пагинация работает корректно только до третьей страницы и если кликнуть по ссылке на любую страницу дальше третьей, появляется ошибка 404.
Теория
Проблема с пагинацией связана с неправильной передачей переменной $paged
или неправильной настройкой запроса WP_Query для архива таксономии. Пагинация в WordPress основывается на правилах перезаписи URL, и если они не соответствуют настройкам цикла, которым выводятся записи, это может привести к ошибке 404.
Если вы используете пользовательский цикл через WP_Query, важно удостовериться, что передача параметра paged
настроена корректно. WordPress базируется на системе запросов, и если ваш запрос сбивается из-за некорректной настройки, это может привести к тому, что для страницы номер 4 или больше, будет выдаваться ошибка 404.
Пример
В вашем первоначальном коде были несколько деталей, которые следовало бы рассмотреть. Простейший способ решения проблемы заключается в использовании хука pre_get_posts
, который позволяет изменять запрос основного цикла WordPress до его выполнения. Вот пример из вашего кода:
function get_tax_posts( $query ) {
if( !is_admin() && $query->is_main_query() && $query->is_tax('venue')) {
$query->set('post_type', 'show' );
$query->set('posts_per_page', '3');
$query->set('meta_key', 'show_date' );
$query->set('order', 'ASC' );
$query->set('orderby', 'meta_value' );
$query->set('meta_query', array(
array(
'key' => 'show_date',
'value' => current_time('Ymd'),
'compare' => '>=',
)
));
$taxquery = array(
array(
'taxonomy' => 'venue',
'field' => 'slug',
'terms' => 'venue-one',
)
);
$query->set('tax_query', $taxquery);
}
}
add_action('pre_get_posts', 'get_tax_posts', 9999);
Таким образом, происходит настройка основного запроса WordPress для архива таксономии "venue". Убедитесь, что аналогичный код действует и для другой категории "venue-two", с учётом соответствующих изменений.
Применение
Для решения проблемы с исчезновением ссылок пагинации стоит воспользоваться встроенной функцией WordPress the_posts_pagination()
, которая автоматически выведет корректные ссылки пагинации при корректной настройке основного запроса:
<?php the_posts_pagination(); ?>
Вы уже упомянули, что применение данной функции помогло с решением этой части проблемы.
Что касается частного случая, когда несколько функций в functions.php
должны активироваться для разных таксономий, необходимо убедиться, что имена функций уникальны, чтобы избежать неожиданных конфликтов и зависимостей вызова.
Если рассматриваются сложные случаи с различными пользовательскими типами записей или таксономиями, всегда полезно проверить основные пути перезаписи URL через панель управления "Постоянные ссылки" и очистить кеши, если вы их используете, например плагин кэша. Это обеспечит корректную работу правил переписи URL и может помочь избежать появления ошибки 404.
Заключение
Проблема с пагинацией, не работающей на страницах архивов категорий, может быть достаточно сложной из-за множества переменных, влияющих на поведение WordPress. Однако при правильной настройке запроса через pre_get_posts
и использовании встроенных функций для отображения пагинации проблему можно эффективно решить. Всегда следует помнить о возможности конфликтов в именах функций и о важности удаления ручных запросов WP_Query, если вы перешли на управление через pre_get_posts
— это поможет избежать ошибок и конфликтов во время выполнения запросов.