I have a custom post type and in the CPT's single-cpt.php file I would like to pull in two posts instead of one.

The two posts will be the post the user clicked in the relevant archive, and the next post in date order (i.e. the default post sorting method of WordPress). The reason for this is the posts are essentially small, useful pieces of information and having two posts pulled in will create a better SEO and user experience.

Normally when I want to pull in a set number of posts on an archive page I would use WP_Query() and set 'posts_per_page' => 2 but out of the box this won't work on a single-cpt.php file because such code pulls in posts that are the most recent, not the post that was clicked on the archive page (and then the next most recent).

What I'm looking for is something that works with the WP loop so each post looks the same, but pulls in two posts (the selected one from the archive and then the next one in date order).

Note: If this isn't possible with WP_Query() any other way to do it would be most welcome.

$newsArticles = new WP_Query(array(
    'posts_per_page' => 2,
    'post_type'=> 'news'
while(  $newsArticles->have_posts()){
        $newsArticles->the_post(); ?>

// HTML content goes here

<?php } ?>
<?php wp_reset_postdata(); ?>

Any help would be amazing.

3 Answers 3


Try this:

$current_id = get_the_ID();
$next_post = get_next_post();
$next_id = $next_post->ID;
$cpt = get_post_type();
$cpt_array = array($current_id, $next_id);
$args = array(
   'post_type' => $cpt,
   'post__in' => $cpt_array,
   'order_by' => 'post_date',
   'order' => 'ASC',
$the_query = new WP_Query($args);
    while($the_query->have_posts() ): $the_query->the_post();
       echo '<h2>'.the_title().'</h2>';

Tested locally and seems to work fine. get the current post id get the next post id get the current post post type run query


If I'm understanding you correctly, on your single CPT template, I'd do something like this:

$next_post = get_next_post();

Which will chronologically get the next page object, which you can then use built in parameters (found here) to output the content parts you need, such as:

echo $next_post->post_title;

Which will output the next pages title.

  • Hi @ben thanks - this isn't what I'm looking for. I really need something that pulls in the selected post and then the next one using the same loop structure so both posts appear in their full glory so to speak.
    – pjk_ok
    Aug 8, 2020 at 0:03
  • Hi Emily. I think this may be the only way to achieve close what you’re looking for. To add, if you created a template part, then you could pull out the current post inside the loop like normal. Below that, using the next post function you can get the next posts ID joined with your template part to output the next post in the exact same format to the original.
    – Ben
    Aug 8, 2020 at 0:13
  • Hi @ben would you be able to show that in code ? I'm struggling to wrap my head around that. Also I edited the question.
    – pjk_ok
    Aug 8, 2020 at 0:18
  • Hi Emily, given your changes it may not be relevant, but here it is all the same.
    – Ben
    Aug 8, 2020 at 0:49

I didn't put it into a template part, but that would be a fairly simple next step I think. Here's what I would do though:

<!-- The original loop -->
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
    <?php the_post_thumbnail( 'medium' ) ?>
    <h3><?php the_title(); ?></h3>
    <span class="date"><?php the_date( ); ?></span> <span class="author"><?php the_author_nickname(); ?></span>
    <?php the_content(); ?>
<?php endwhile; endif; ?>

<!-- Get Next Post Data -->
<?php $next_post = get_next_post(); ?>

<!-- Format Next Post to mimic the above -->
<img src="<?php get_the_post_thumbnail_url( $next_post->ID, 'medium' ); ?>">
<h3><?php echo $next_post->post_title; ?></h3>
<span class="date"><?php echo $next_post->post_date; ?></span> <span class="author"><?php echo get_the_author_nickname( $next_post->post_author ); ?></span>
<?php echo get_the_content( $next_post->ID ); ?>

This echos the original loop at the top of the page, when inside the loop. Then, the loop ends, and the next post is called. The markup for that next post call is identical to the original post, thus you would end up with a like-for-like post layout on one post page.

  • Thanks Ben. This kind of works although the <?php echo get_the_content( $next_post->ID ); ?> shows the current post content not the next post content? Also I looked in the developer docs and there was hardly any info. Where did you find out what object parameters to use? I have some categories and other stuff I need to add too and I'm thinking the $next_post->ID code may be incorrect with regards to the content.
    – pjk_ok
    Aug 8, 2020 at 21:56
  • This has ultimately got the post object by calling the next post function. The parameter for this can be found at developer.wordpress.org/reference/functions/get_post/…. Is it only the content that is showing the current posts content? If so, then that suggests that the ID is being called correctly elsewhere on the page. In fact, you'd probably be better using $next_post->post_content, it was late when I wrote that last night! That should work a bit more reliably for you.
    – Ben
    Aug 8, 2020 at 23:13
  • Hi @ben this still doesn't work. I'm going to put a bounty on the question to see if that helps at all. Thanks for taking the time to answer though.
    – pjk_ok
    Aug 9, 2020 at 23:26

Your Answer

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

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