Question

Let's assume that I have the following posts with the following titles:

  • PostA (is assigned to the 'category 1')
  • PostX (category 2)
  • PostB (category 1)
  • PostC (category 1)
  • PostD (category 1)
  • PostY (category 2)
  • PostE (category 1)
    ...

When a visitor will read the PostC, how can I display in the sidebar:


Previous Posts:
'PostA' (these are links here, of course)
'PostB'

Next Posts:
'PostD'
'PostE'


IOW the previous and the next 2 posts from the same category. (If a post has more categories we will choose the 1st one or the last one - it doesn't matter very much).

Also, if it is impossible to display the prev & next two posts it is acceptable also only one previous and next post. (I know that there are some WP functions for this but we prefer if it's possible two posts).

Also, of course, we want to display the first 'n' characters from the title (let's say 22). We don't want to display a static text like 'Next Post' or similar.

TIA

Was it helpful?

Solution

The existing WordPress functions are only for displaying one previous or next post. I quickly wrote functions to display any number of posts.

Paste the following in your theme functions.php file:

function custom_get_adjacent_posts( $in_same_cat = false, $previous = true, $limit = 2 ) {
    global $post, $wpdb;

    $op = $previous ? '<' : '>';

    if ( $in_same_cat ) {
        $cat_array = wp_get_object_terms($post->ID, 'category', array('fields' => 'ids'));

        $join = " INNER JOIN $wpdb->term_relationships AS tr ON p.ID = tr.object_id INNER JOIN $wpdb->term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id AND tt.taxonomy = 'category' AND tt.term_id IN (" . implode(',', $cat_array) . ")";
    }

    $posts = $wpdb->get_results( $wpdb->prepare( "SELECT p.* FROM wp_posts AS p $join WHERE p.post_date $op '%s' AND p.post_type = 'post' AND p.post_status = 'publish' ORDER BY p.post_date DESC LIMIT $limit", $post->post_date, $post->post_type ) );

    return $posts;
}

function custom_adjacent_posts_links( $in_same_cat = false, $previous = true, $limit = 2 ) {
    $prev_posts = custom_get_adjacent_posts( $in_same_cat, $previous, $limit );
    if( !empty($prev_posts) ) {
        echo ($previous) ? '<h3>Previous Posts:</h3>' : '<h3>Next Posts:</h3>';
        echo '<ul>';
        foreach( $prev_posts as $prev_post ) {
            $title = apply_filters('the_title', $prev_post->post_title, $prev_post->ID);
            echo '<li><a href="' . get_permalink( $prev_post ) . '">' .$title . '</a></li>';
        }
        echo '</ul>';
    }
}

In your sidebar file, where you want to display the posts, use custom_adjacent_posts_links( true ); to display the two previous posts in the same category and custom_adjacent_posts_links( true, false ); to display the next two posts in the same category.

Licensed under: CC-BY-SA with attribution
Not affiliated with wordpress.stackexchange
scroll top