3

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.

<?php 
$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
+100

Try this:

<?php
$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);
if($the_query->have_posts()):
    while($the_query->have_posts() ): $the_query->the_post();
       echo '<h2>'.the_title().'</h2>';
    endwhile;
endif;
wp_reset_postdata();
?>

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

| improve this answer | |
3

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.

| improve this answer | |
  • 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. – The Chewy Aug 8 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 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. – The Chewy Aug 8 at 0:18
  • Hi Emily, given your changes it may not be relevant, but here it is all the same. – Ben Aug 8 at 0:49
3

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.

| improve this answer | |
  • 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. – The Chewy Aug 8 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 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. – The Chewy Aug 9 at 23:26

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.