I have my main blog, which lists all posts.
I also have a category page that lists only posts from 1 category.
Main Blog
- Post #1
- Post #2
- Post #3
- Post #4
- Post #5
Category A Page
Category B Page
If a user clicks to look at a post, and then uses the default next/prev link functions, there is no way for WordPress to know which post should be next.
For example, if the user is looking at Post #3, should the next post be #4 or #5? It all depends on where the user came from.
So I wrote the following code to answer this problem and thought I'd share it.
NOTE: I know that this is not the most efficient way to do this, especially if you have thousands of posts. I'd be interested in seeing better ways to get the next post.
Add the following to your functions.php file:
/*
* Session Tracking
*/
add_action('init', 'start_session', 1);
function start_session() {
if(!session_id()) {
session_start();
}
}
// Update Cookie trail
function update_cookie_trail() {
$_SESSION['ref_category'] = get_query_var('cat');
}
/*
* Return next post based off of cookies
*/
function next_post_from_session($text, $categories) {
global $post;
$cat_array = explode(',', $categories);
$cat_array[] = $_SESSION['ref_category'];
// Get all posts, exclude Hidden cat
$args = array(
'numberposts' => -1,
'category' => implode(',', $cat_array),
'orderby' => 'post_date',
'order' => 'DESC',
'post_type' => 'post',
'post_status' => 'publish',
);
$allPosts = get_posts( $args );
$index = 0;
foreach( $allPosts as $thePost ) {
$index++;
if($post->ID == $thePost->ID) {
$nextPost = $allPosts[$index++];
$url = get_permalink($nextPost->ID);
$a = '<a href="'.$url.'" title="'.esc_attr($nextPost->post_title).'" />'.$text.'</a>';
return $a;
}
}
}
/*
* Return previous post based off of cookies
*/
function previous_post_from_session($text, $categories) {
global $post;
$cat_array = explode(',', $categories);
$cat_array[] = $_SESSION['ref_category'];
// Get all posts, exclude Hidden cat
$args = array(
'numberposts' => -1,
'category' => implode(',', $cat_array),
'orderby' => 'post_date',
'order' => 'DESC',
'post_type' => 'post',
'post_status' => 'publish',
);
$allPosts = get_posts( $args );
$index = 0;
foreach( $allPosts as $thePost ) {
if($post->ID == $thePost->ID) {
$prevPost = $allPosts[$index-1];
$url = get_permalink($prevPost->ID);
$a = '<a href="'.$url.'" title="'.esc_attr($prevPost->post_title).'" />'.$text.'</a>';
return $a;
}
$index++;
}
}
/*
* Generate a "back" URL to the previous category page based off session data
*/
function previous_category_permalink() {
$ref_url = $_SESSION['ref_category'];
return get_category_link($ref_url);
}
And then on any category.php or page where you show several blog posts (like a "related posts" section), run this function:
update_cookie_trail();
Then on your single.php you can use the following functions.
<?php echo next_post_from_session('Next', '-24, 10'); ?>
<a class="close" href="<?php echo previous_category_permalink(); ?>">
Back
</a>
<?php echo previous_post_from_session('Previous Post', '-24, 10'); ?>
The '-24, 10' is a parameter that allows you to exclude, or specifically include categories via comma separated ID's.