0

At the bottom of single.php, I want to display "card" links to the next and previous posts in chronological order. This is pretty easy thanks to get_next_post() and get_previous_post, no problems so far.

However, I want to change that feed when on the most recent post -- that post won't have a next post. Instead of an empty space in my layout, I'd like to display the previous post and its previous post. So the two previous posts instead of just one.

I know how to check if we're on the most recent post, I'm just not sure how to properly call the multiple previous posts. My basic code structure is:

if ( have_posts() ) {
     while ( have_posts() ) { the_post();
          // output current post here
     }

     $next = get_next_post();
     if( $next ) {
          $id = $next->ID;
          $url = get_the_permalink( $id );
          $title = $next->post_title;
          $date = get_the_date( '', $next );
          // use these variables to output link to next post
     }

     $prev = get_previous_post();
     if( $prev ) {
          $id = $prev->ID;
          $url = get_the_permalink( $id );
          $title = $prev->post_title;
          $date = get_the_date( '', $prev );
          // use these variables to output link to previous post
     }

     // If there's no next post, that means we're on the most recent post.
     // To fill the space, let's pull the 2nd previous post.
     if( !$next ) {
          // Make sure there's a previous post
          if( $prev ) {

               // Conditions are perfect. Now how do I grab that 2nd previous post??

          }
     }
 }

I'm sure it's some basic query issue. What am I missing?

1 Answer 1

0

I hope there are multiple ways to accomplish this, but I suggest you use the following simpler function for this purpose. This is an attempt to grab a post for the current post which excludes it and the previous post:

// A custom function in your functions.php file
function get_related_previous_post($previous = 0) {

    global $post; // take current post object
    $category_ids = array();
    $categories = get_the_category($post->ID); // current post categories
    
    if ($categories) {
        foreach ($categories as $individual_category) {
            $category_ids[] = $individual_category->term_id;
        }
    }

    $args = array(
        'post__not_in' => array($post->ID, $previous), // exclude posts
        'posts_per_page' => '1',
        'orderby' => 'date',
        'order'   => 'DESC',
        'category__in' => $category_ids // apply same categories 
    );
    $prevprev_id = 0;
    $my_query = new WP_Query( $args );
    if ($my_query->have_posts()) {

        while ($my_query->have_posts()) {
            $my_query->the_post();
            // Do your stuff
            $prevprev_id = $post->ID;
        }
    }
    wp_reset_postdata();
    return get_post($prevprev_id);
}

Call the function in your single.php file like:

if (!$next) {
    // Make sure there's a previous post
    if ($prev) {
        $prevprev = get_related_previous_post($prev->ID);
    }
}
5
  • Awesome! This is a really smart solution and looks like it will do what I need it to. Will post again once I've figured out how to adapt to the rest of my code. Thanks!
    – doofusb0y
    Oct 15 at 14:37
  • Looks like I'm getting stuck on the implementation. This will echo the correct post ID, so the query is good. What I really need to do is store the post object as a variable, so I can choose what to echo where. Ideally it would work the same as $next = get_next_post(); so that in single.php I'd be able to do something like $related = get_related_previous_post($prev->ID); That way I'd be able to grab and echo the parts of $related I want, like I can with $next and $prev. Any ideas on how to achieve that?
    – doofusb0y
    Oct 15 at 14:53
  • Since you have the ID of the prev/prev post, we need to return the post object. Save the ID in a variable and take the post object with the get_post function and return at the end of the function. ... $prevprev_id = 0; $my_query = new WP_Query( $args ); if ($my_query->have_posts()) { while ($my_query->have_posts()) { $my_query->the_post(); echo $post->ID; $prevprev_id = $post->ID; // Do your stuff } } wp_reset_postdata(); return get_post($prevprev_id);
    – Baljka Gan
    Oct 16 at 2:10
  • Updated the main message. Hope you find a clue about returning the object
    – Baljka Gan
    Oct 16 at 2:17
  • 1
    That did it! Thanks again for all your help!
    – doofusb0y
    Oct 16 at 23:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.