Отображение записей из той же категории с помощью ссылок на следующую/предыдущую запись
Я использую этот код, но когда я кликаю на ссылку следующей/предыдущей записи, меня перенаправляет на следующую/предыдущую запись из другой категории.
previous_post_link( '%link', 'Предыдущая запись в категории', $in_same_term = true );
next_post_link( '%link', 'Следующая запись в категории', $in_same_term = true );
Я пытаюсь исправить проблему, используя эту статью.
Вот код, который я использую для записей и категорий, причем я не использую произвольные типы записей и категории:
$post_id = $post->ID;
$cat = get_the_category();
$current_cat_id = $cat[0]->cat_ID;
$args = array(
'category' => $current_cat_id,
'orderby' => 'post_date',
'order' => 'DESC'
);
$posts = get_posts( $args );
foreach( $posts as $post ) {
echo $post->post_content;
}
previous_post_link( '%link', 'Предыдущая запись в категории', $in_same_term = true );
next_post_link( '%link', 'Следующая запись в категории', $in_same_term = true );
По сути, код получает все записи на основе категории, и теперь я хочу, чтобы ссылки на следующую/предыдущую запись работали только для этой конкретной категории.
Вот код для получения предыдущей и следующей ссылок на записи в рамках одной категории:
<?php
$post_id = $post->ID; // ID текущей записи
$cat = get_the_category();
$current_cat_id = $cat[0]->cat_ID; // ID текущей категории
$args = array(
'category' => $current_cat_id,
'orderby' => 'post_date',
'order' => 'DESC'
);
$posts = get_posts( $args );
// получаем ID записей из результата get_posts
$ids = array();
foreach ( $posts as $thepost ) {
$ids[] = $thepost->ID;
}
// получаем и выводим предыдущую и следующую запись в той же категории
$thisindex = array_search( $post_id, $ids );
$previd = isset( $ids[ $thisindex - 1 ] ) ? $ids[ $thisindex - 1 ] : false;
$nextid = isset( $ids[ $thisindex + 1 ] ) ? $ids[ $thisindex + 1 ] : false;
if (false !== $previd ) {
?><a rel="prev" href="<?php echo get_permalink($previd) ?>">Предыдущая</a><?php
}
if (false !== $nextid ) {
?><a rel="next" href="<?php echo get_permalink($nextid) ?>">Следующая</a><?php
}

+1 Это именно то, что я искал. Моё требование состояло в сортировке по полю Order в окне Edit Page Attributes. Поэтому я изменил аргументы $args на $args = array('category'=>$current_cat_id,'orderby'=>'menu_order','order'=> 'ASC');
, и это решило мою проблему. Огромное спасибо за предоставленное решение!

Функции previous_post_link
и next_post_link
принимают по пять параметров:
$format
: Строка формата для ссылки, определяет, что будет выводиться до и после ссылки
$link
: Текст ссылки для отображения
$in_same_term
: Должен ли следующий/предыдущий пост находиться в том же таксономическом термине, что и текущий пост
$excluded_terms
: Термины, из которых нужно исключить посты
$taxonomy
: Таксономия, которая будет использоваться, когда $in_same_term
равен true
Как видите, параметр $in_same_term
делает именно то, что вам нужно. Однако в вашем примере кода он используется неверно. Вы фактически передаёте результат присваивания true
переменной $in_same_term
. Это не сработает: передача аргумента осуществляется простой передачей значения:
previous_post_link( '%link', 'Предыдущий пост в категории', true );
next_post_link( '%link', 'Следующий пост в категории', true );
Примечание: (обновлено после уточнения вопроса автором)
Проблема в том, что previous_post_link
и next_post_link
используют глобальный объект поста, который вы перезаписываете. Чтобы этого избежать, используйте в вашем цикле $posts
другую переменную, например $singlepost
:
foreach ( $posts as $singlepost ) {
echo $singlepost->post_content
}
Таким образом, глобальный объект $post
сохранится. Альтернативно, вы можете сохранить глобальный объект поста во временную переменную и сбросить $post
позже, но это действительно необходимо только если вы вызываете setup_postdata
(чего в вашем случае нет).

Нам потребуется немного больше информации :-). Вы используете пользовательский тип записи или таксономию, или просто "Записи" и "Рубрики"? Есть ли где-то, где мы можем увидеть, что именно идёт не так?

Ваш код не имеет для меня смысла, кроме того, что содержит синтаксическую ошибку. В текущем виде, при клике на запись со страницы блога, вы переходите к одиночному просмотру записи, как и должно быть. Только эта запись отображается в single.php.
Проблема начинается, когда вы кликаете на ссылки записей, неважно, предыдущая это или следующая запись. После загрузки предыдущей/следующей страницы возвращаются все записи из этой категории. Именно так вы закодировали свой single.php, поэтому ссылки на записи не работают так, как вы ожидаете.
Я бы не использовал get_posts()
для настройки цикла на странице single.php. Я бы просто использовал стандартный корректный цикл. Пожалуйста, ознакомьтесь со страницей в кодексе о разработке тем.
Вот пример single.php, который будет работать как ожидается:
<?php
get_header(); ?>
<div id="main-content" class="main-content">
<div id="primary" class="content-area">
<div id="content" class="site-content" role="main">
<?php
// Начало цикла.
while ( have_posts() ) : the_post(); ?>
<?php
get_template_part( 'content', get_post_format() );
// Навигация по предыдущей/следующей записи.
previous_post_link( '%link', 'Предыдущая запись в категории', true );
next_post_link( '%link', 'Следующая запись в категории', true );
// Если комментарии открыты или есть хотя бы один, подгружаем шаблон комментариев.
if ( comments_open() || get_comments_number() ) {
comments_template();
}
endwhile;
?>
</div><!-- #content -->
</div><!-- #primary -->
<?php get_sidebar( 'content' ); ?>
</div><!-- #main-content -->
<?php
get_footer();
Как указано в другом ответе, прочтите о том, как использовать next_post_link
и previous_post_link
.

Спасибо за ответ, не могли бы вы указать, где синтаксическая ошибка в моем коде

Пожалуйста, установите debug в значение true в wp-config. Это должно вам сильно помочь

Вам стоит попробовать то, что я сказал, ваш код не будет работать, с вашим текущим кодом он просто будет перезагружать одну и ту же страницу снова и снова с ссылками на записи

У меня была такая же проблема, ПЛЮС мне нужно было всё это для пользовательского типа записи и пользовательской таксономии. user54318 направил меня в правильном направлении, которое не поддерживает произвольные типы записей, поэтому я тоже поделюсь своими результатами здесь:
// Получаем пользовательские таксономии.
$terms = wp_get_post_terms( get_the_ID(), 'product_cat' ); // Последний аргумент — пользовательская таксономия. Измените на нужную
// Проходим по всем терминам и фильтруем нужный.
$stay_in = array();
foreach( $terms as $term ) :
/* Этот цикл ищет категорию, которая является дочерней для категории с ID 37. Измените под свои нужды.
Важно только построить массив ID терминов, которые будут включены в поведение предыдущий/следующий, поэтому если вы уже знаете свои ID, вы можете использовать что-то вроде $stay_in = array( 43 ); и пропустить весь этот цикл.. */
if ( $term->parent == 37 ) :
$stay_in[] = $term->term_id;
break; // Выходим из цикла foreach, если нашли.
endif;
endforeach;
// Получаем все ID записей, которые находятся в определённой мной категории
$args = array(
'post_type' => 'product', // Пользовательский тип записи
'posts_per_page' => -1,
'tax_query' => array(
array(
'taxonomy' => 'product_cat', // Пользовательская таксономия
'field' => 'term_id',
'terms' => $stay_in,
'operator' => 'IN', // Измените под свои нужды.. IN, NOT IN, AND, EXISTS, NOT EXISTS
)
),
'orderby' => 'post_date',
'order' => 'ASC',
'fields' => 'ids', // Возвращаем только ID записей, а не все объекты записей
);
$all_posts = new WP_Query( $args );
// Ищем текущую запись по её ID и ищем предыдущий/следующий ID
$this_index = array_search( $post->ID, $all_posts->posts );
$prev_id = $all_posts->posts[ $this_index - 1 ];
$next_id = $all_posts->posts[ $this_index + 1 ];
// Выводим ссылки, если предыдущий/следующий существует
if ( ! empty( $prev_id ) ) :
echo '<a rel="prev" href="' . get_permalink( $prev_id ) . '">' . __( 'предыдущий', 'your_theme_text_domain' ) . '</a>';
endif;
if ( ! empty( $next_id ) ) :
echo '<a rel="next" href="' . get_permalink( $next_id ) . '">' . __( 'следующий', 'your_theme_text_domain' ) . '</a>';
endif;
wp_reset_postdata();
