Wordpress - Get Previous & Next posts by Post ID

Take a look at get_previous_post() and get_next_post() and you'll see they both use the get_adjacent_post() to find the previous or next post.

Let's say you want to fetch the ID of the immediately previous post based on the current post's ID. This is what you'd do:

function get_previous_post_id( $post_id ) {
    // Get a global post reference since get_adjacent_post() references it
    global $post;

    // Store the existing post object for later so we don't lose it
    $oldGlobal = $post;

    // Get the post object for the specified post and place it in the global variable
    $post = get_post( $post_id );

    // Get the post object for the previous post
    $previous_post = get_previous_post();

    // Reset our global object
    $post = $oldGlobal;

    if ( '' == $previous_post ) {
        return 0;
    }

    return $previous_post->ID;
}

You can do a similar thing to fetch the next post's ID ... and you can do this recursively if you need to get the previous previous post:

$two_posts_ago = get_previous_post_id( get_previous_post_id( $post->ID ) );

TL;DR

Essentially, both get_previous_post() and get_next_post() reference a global $post object to do their selection. You need to set this object up before calling either function or they won't know what post to use as a reference for next/previous.

The wrapper function above just sets up the global $post for you based on a passed-in ID. You could have it return the entire object for the previous post rather than the ID, it's entirely up to you.


Here, you can get adjacent post for specific post type with custom sql query & with filter get_{$adjacent}_post_where where default adjacent is previous. Also result depends on $current_post_date & comparison operator $op.

function bm_get_adjacent_post( $post_id, $author_id, $previous = 1 ) {
global $wpdb;

if ( ( ! $post = get_post( $post_id ) )  )
    return null;

$current_post_date = $post->post_date;

$adjacent = $previous ? 'previous' : 'next';
$op = $previous ? '<' : '>';
$order = $previous ? 'DESC' : 'ASC';

$where = apply_filters( "get_{$adjacent}_post_where", $wpdb->prepare( "WHERE  p.post_date $op %s AND p.post_type = %s AND p.post_status = 'publish' AND p.post_author = %d", $current_post_date, 'projects' , $author_id ), '', '' );
$sort  = apply_filters( "get_{$adjacent}_post_sort", "ORDER BY p.post_date $order LIMIT 1" );

$query = "SELECT p.ID FROM $wpdb->posts AS p $where $sort";
//echo $query;
$result = $wpdb->get_var( $query );
if ( null === $result )
    $result = '';
if ( $result )
    $result = get_post( $result );

return $result;
}