Отображение записей из той же категории с помощью ссылок на следующую/предыдущую запись

17 июн. 2014 г., 10:23:36
Просмотры: 45.5K
Голосов: 11

Я использую этот код, но когда я кликаю на ссылку следующей/предыдущей записи, меня перенаправляет на следующую/предыдущую запись из другой категории.

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 );

По сути, код получает все записи на основе категории, и теперь я хочу, чтобы ссылки на следующую/предыдущую запись работали только для этой конкретной категории.

6
Комментарии

Вы используете этот код в single.php?

Pieter Goosen Pieter Goosen
17 июн. 2014 г. 13:54:11

Для какого поста вы хотите отобразить ссылки на предыдущий/следующий пост? Для последнего поста в массиве $posts из предоставленного вами кода, или для основного поста на текущей странице?

engelen engelen
17 июн. 2014 г. 14:05:11

@pieter Goosen: да, я использую этот код в single.php

user54318 user54318
17 июн. 2014 г. 14:11:11

@engelen Я отображаю все записи, относящиеся к категории на текущей странице, и теперь хочу, чтобы ссылки "следующая" и "предыдущая" были ограничены только текущей категорией

user54318 user54318
17 июн. 2014 г. 14:27:52

Хорошо, что это за страница? Страница отдельной записи, архив категории, ..?

engelen engelen
17 июн. 2014 г. 14:41:11

@engelen: это страница отдельной записи

user54318 user54318
17 июн. 2014 г. 14:47:59
Показать остальные 1 комментариев
Все ответы на вопрос 5
3
23

Вот код для получения предыдущей и следующей ссылок на записи в рамках одной категории:

<?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
}
20 июн. 2014 г. 13:34:10
Комментарии

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

Devner Devner
8 окт. 2014 г. 10:25:51

Спасибо, очень полезно для меня

Sumit Kumar Gupta Sumit Kumar Gupta
3 янв. 2020 г. 22:48:51

Куда нужно вставить этот код?

Shivam Sahil Shivam Sahil
7 нояб. 2020 г. 17:53:20
4

Функции 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 (чего в вашем случае нет).

17 июн. 2014 г. 10:31:33
Комментарии

Спасибо за быстрый ответ. Я всё ещё получаю тот же результат.

user54318 user54318
17 июн. 2014 г. 10:50:11

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

engelen engelen
17 июн. 2014 г. 10:52:03

я обновил свой вопрос

user54318 user54318
17 июн. 2014 г. 12:08:46

Я обновил свой ответ соответствующим образом.

engelen engelen
17 июн. 2014 г. 14:56:08
6

Ваш код не имеет для меня смысла, кроме того, что содержит синтаксическую ошибку. В текущем виде, при клике на запись со страницы блога, вы переходите к одиночному просмотру записи, как и должно быть. Только эта запись отображается в 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.

17 июн. 2014 г. 15:06:15
Комментарии

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

user54318 user54318
17 июн. 2014 г. 15:18:15

В этой строке echo $post->post_content забыли ;

Pieter Goosen Pieter Goosen
17 июн. 2014 г. 15:19:49

О, да, понял :)

user54318 user54318
17 июн. 2014 г. 15:20:51

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

Pieter Goosen Pieter Goosen
17 июн. 2014 г. 15:22:00

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

Pieter Goosen Pieter Goosen
17 июн. 2014 г. 15:24:13

Хмм, да, я нашел решение своей проблемы. Думаю, я не совсем правильно задал вопрос. В любом случае, спасибо за ваши предложения. Я опубликовал решение своей проблемы

user54318 user54318
20 июн. 2014 г. 13:35:44
Показать остальные 1 комментариев
1

У меня была такая же проблема, ПЛЮС мне нужно было всё это для пользовательского типа записи и пользовательской таксономии. 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();
9 нояб. 2015 г. 15:56:25
Комментарии

Спасибо, спасибо, огромное спасибо!!!!

Victor Sokoliuk Victor Sokoliuk
12 янв. 2022 г. 17:21:26
0
<?php next_post_link( '%link', '%title', TRUE, '0' , 'category' ); ?>
<?php previous_post_link( '%link', '%title', TRUE, '0' , 'category' ); ?>

Где 0 - это ID исключаемой категории

21 дек. 2022 г. 08:57:30