Wordpress - Display posts from the same category using next/previous post link
Here is the code to get category based previous and next links on posts:
<?php
$post_id = $post->ID; // current post ID
$cat = get_the_category();
$current_cat_id = $cat[0]->cat_ID; // current category ID
$args = array(
'category' => $current_cat_id,
'orderby' => 'post_date',
'order' => 'DESC'
);
$posts = get_posts( $args );
// get IDs of posts retrieved from get_posts
$ids = array();
foreach ( $posts as $thepost ) {
$ids[] = $thepost->ID;
}
// get and echo previous and next post in the same category
$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) ?>">Previous</a><?php
}
if (false !== $nextid ) {
?><a rel="next" href="<?php echo get_permalink($nextid) ?>">Next</a><?php
}
The previous_post_link
and next_post_link
functions both have five parameters:
$format
: Format string for the link, used to control what comes before and after the link
$link
: Link text to display
$in_same_term
: Whether the next/previous post must be in the same taxonomy term as the current post
$excluded_terms
: Terms from which to exclude posts
$taxonomy
: The taxonomy to use when $in_same_term
is true
As you can see, the $in_same_term
parameter does exactly what you need. However, you're not using it correctly in your sample code. You're actually passing the result of assigning true
to a variable $in_same_term
. This won't work: passing an argument is as simple as passing a value:
previous_post_link( '%link', 'Prev post in category', true );
next_post_link( '%link', 'Next post in category', true );
Edit: (edited after OP updated his question)
The problem is that previous_post_link
and next_post_link
use the global post object, which you're overwriting. To prevent this, use another variable name in your $posts
-loop, such as $singlepost
:
foreach ( $posts as $singlepost ) {
echo $singlepost->post_content
}
This way, the global $post
object is preserved. Alternatively, you could store the global post object in a temporary variable and reset $post
again later, but that's only really necessary if you're calling setup_postdata
(which you aren't).