1

I am trying to retrieve the previous and the 2nd previous posts' featured image as well as the two next posts' featured image.

<div id="cooler-nav" class="navigation row">
<?php $prevPost = get_previous_post(true);
    if($prevPost) {?>
    <div class="nav-box previous col-md-3">
    <?php $prevthumbnail = get_the_post_thumbnail($prevPost->ID, array('medium'));}?>
    <?php previous_post_link('%link',"$prevthumbnail  %title", TRUE); ?>
    </div>

<?php $prevprevPost = get_previous_post(get_previous_post(true));
    if($prevprevPost) {?>
    <div class="nav-box previous col-md-3">
    <?php $prevprevthumbnail = get_the_post_thumbnail($prevprevPost->ID, array('medium'));}?>
    <?php previous_post_link('%link',"$prevprevthumbnail  %title", TRUE); ?>
    </div>

<?php $nextPost = get_next_post(true);
    if($nextPost) { ?>
    <div class="nav-box next col-md-3">
    <?php $nextthumbnail = get_the_post_thumbnail($nextPost->ID, array('medium') ); } ?>
    <?php next_post_link('%link',"$nextthumbnail  %title", TRUE); ?>
    </div>

<?php $nextnextPost = get_next_post(get_next_post(true));
    if($nextnextPost) {?>
    <div class="nav-box next col-md-3">
    <?php $nextnextthumbnail = get_the_post_thumbnail($nextnextPost->ID, array('medium'));}?>
    <?php next_post_link('%link',"$nextnextthumbnail  %title", TRUE); ?>
    </div>
</div><!--#cooler-nav div -->

Instead of next and previous links, I would like to show four featured images of the surrounding posts.

  • what is the result of your posted code? – Michael Jan 4 '15 at 19:00
  • I get two pictures of the previous post and two of the next post... @Michael – HannesH Jan 4 '15 at 19:43
  • You are using invalid values in get_previous_post() and get_next_post(). You are better of here writing your own function – Pieter Goosen Jan 5 '15 at 7:09
  • I will see what I can come up with. Have an idea here. Will most probablyt post somewhere today :-) – Pieter Goosen Jan 5 '15 at 7:34
  • Really appreciate that and it is very needed! :) I am trying as well, but not really working... @PieterGoosen – HannesH Jan 5 '15 at 7:41
1

As I previously said in a comment

You are using invalid values in get_previous_post() and get_next_post(). You are better of here writing your own function

I came up with the following. :

  • Get an array of all the posts and determine the current post's position.

  • Get the post ID's of the posts on both sides of the current post. The amount of ID's depend on the value set by $x_from_current. The current default is one, which means it will retrieve the ID next to the current post. If set to two, it will retrieve two posts next to the current post

  • You also have the option to set the function to get the next/previous posts from the same term as the current post. Just remember to set the taxonomy then as well as this defaults to category

I have decided to only return the post ID's of the adjacent posts as you need to show thumbnails, in which case you will only need post ID's

Here is the function. I have commented it well so that you can understand how the function works and how to use it

function get_x_post_from_current( $x_from_current, $in_same_term, $taxonomy, $previous ) {

    // Get the current single post ID. To be save, use get_queried_object_id()
    $current_post_id = get_queried_object_id();

    // Option to choose if adjacent posts should be from the same term. Should then set $taxonomy
    if( true === $in_same_term ) {

        /**
         * Use wp_get_post_terms() to retrieve the terms/categories the current post belongs
         * to
         *
         * @see http://codex.wordpress.org/Function_Reference/wp_get_post_terms
         *
        */ 
        $terms = wp_get_post_terms( $current_post_id, $taxonomy, ['fields' => 'ids'] );

        if ( ! empty( $terms ) && ! is_wp_error( $terms ) ){

        /**
         * Use tax_query to retrieve a list of posts from the same term as the current post.
         * To speed up the query, get only post ID's. We don't need any other field's info
         *
         * @see http://codex.wordpress.org/Class_Reference/WP_Query#Taxonomy_Parameters
        */ 
        $args = [
            'posts_per_page' => -1,
            'fields' => 'ids',
            'tax_query' => [
                [
                    'taxonomy' => $taxonomy,
                    'field' => 'term_id',
                    'terms' => $terms[0],
                    'include_children' => false,
                ]
            ]       
        ];

        }

    }else{

        // Default if $in_same_term is false
        $args = [
            'posts_per_page' => -1,
            'fields' => 'ids'
        ];

    }

    $q = new WP_Query( $args );

    // Get the current post position. Will be used to determine adjacent posts
    $current_post_position = array_search( $current_post_id, $q->posts );

    /**
     * Previous posts = Newer posts
     * Next Posts = Older posts
     *
     * If $previous is true, reverse array, use array_slice to get the desired amount 
     * of ID's on the left of the current post. Reverse that array to keep synchronous order
     *
     * If $previous is false, slice the array to the right of the current post
     *
    */ 
    if( true === $previous ) {

        $reverse_position   = count( $q->posts ) - ( $current_post_position + 1 );
        $array_reverse      = array_reverse( $q->posts );
        $keys   = array_slice( $array_reverse, $reverse_position + 1, $x_from_current );

    }else{

        $keys = array_slice( $q->posts, $current_post_position + 1, $x_from_current );

    }

    // Returns an array of post ID's or an empty string if no next/previous post is found
    return $keys;

}

// Get the previous post's ID's. Amount of ID's to retrieve is set by $x_from_current
function get_previous_x_post_id( $x_from_current = 1, $in_same_term = false, $taxonomy = 'category' ) {

    return get_x_post_from_current( $x_from_current,$in_same_term, $taxonomy, true );

}

// Get the next post's ID's. Amount of ID's to retrieve is set by $x_from_current
function get_next_x_post_id( $x_from_current = 1, $in_same_term = false, $taxonomy = 'category' ) {

    return get_x_post_from_current( $x_from_current,$in_same_term, $taxonomy, false ); 

}

This is how you should use the functions in your single.php. In your case you need two posts on both sides (next/previous posts)

$previous_posts = get_previous_x_post_id( 2 ); 
?><pre><?php var_dump($previous_posts); ?></pre><?php // Just to see the output 

if( $previous_posts ) {

    foreach ( $previous_posts as $previous_post ) {

        // $previous_post holds the post ID. Use $previous_post to return the post thumbnail

        //Get the post title
        $get_post = get_post( $previous_post );
        echo apply_filters( 'the_title', $get_post->post_title ); 

     }

}

Do the same for next posts.

This is just the minimum. You can extend it like you see fit. You can also have a look at this post I have recently done. This is quite an extensive single post pagination function that uses referrers and multiple post types if needed. You can very easily build this functionality in there

EDITS AS PER COMMENTS

For example I would like to oreder them from left to right so, 1,2,4,5. But now it is ordered in 2,1,5,4 and I dont want to turn them around

In the original code, for some unknown reason, I went and reversed the returned array of post ids for previous posts. That is now fixed (or according to knowledge, I can't unfortunately test anything now)

I would like to add the title beneath the thumbnail can I change the fields to ids and title?

There is no option to return just post titles. The best work around here would be to use the post ids that is returned by the function and using them with get_post to get the specific post and from there use the title of the post.

It would be really expensive to change the function itself to accomodate this, as you will need to retrieve all posts in full, and if you have a thousand posts, you run the danger of timing out. That is why I went with the idea to just get all the post ID's as this is quick and not very expensive. It is also way better to make four small db queries to get the four relevant post's info

Please see the code above for the updated versions

  • It worked great thank you! I only have one little issue... If I am at post number 3 for the moment and I get the thumbnails form post 1-2 and 4-5 they are ordered in the wrong way. For example I would like to oreder them from left to right so, 1,2,4,5. But now it is ordered in 2,1,5,4 and I dont want to turn them around.Again thanks for the great answer! – HannesH Jan 6 '15 at 9:09
  • And if I would like to add the title beneath the thumbnail can I change the fields to ids and title? – HannesH Jan 6 '15 at 9:16
  • I have updated the code and answer above. Hope that helps. Enjoy :-) – Pieter Goosen Jan 6 '15 at 9:42
  • Thanks worked great! But add something in style width $sliced_reverse = array_slice( $q->posts, $current_post_position + 1, $x_from_current ); $keys = array_reverse( $sliced_reverse ); to make the thumbnails come in the right order even for previous posts. :) To make it complete! Thanks, Hannes – HannesH Jan 7 '15 at 10:02
  • My pleasure, and thanks for the suggestion :-). Enjoy – Pieter Goosen Jan 7 '15 at 10:24
0

The trick is that this function only works on current post. But that is something that you can adjust.

So in principle something like this should work (not tested):

global $post;
$post = get_next_post();
setup_postdata( $post ); // the next is now current
// do things
$post = get_next_post(); // and this time we got the next for next
// do more things
wp_reset_postdata(); // clean up when we are done

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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