get_posts works in the page template but not in a shortcode

I am trying to write a shortcode, which includes ‘get_posts’ in order to get the blog posts data and then display the 3 most recent on the page.

This code works within the template. However, when I put it into a shortcode, within output buffering (ob_start), it fails to retrieve the posts. Instead, it takes the current page itself and loops through that instead (in this case the homepage).

Any idea how I can get it to loop through the posts as originally intended?

Here is the code that works in the template:

<?php $lastposts = get_posts( array(‘posts_per_page’ => 3) );?>
<?php if ( $lastposts ) {
foreach ( $lastposts as $post ) :
setup_postdata( $post ); ?>
<div class=”single_post” onclick=”location.href = ‘<?php the_permalink(); ?>’;”>
<div class=”postbox” style=”background-image: url(‘<?php echo catch_first_image() ?>’);”>
<div class=”pink_cover”>
<div class=”text-center datebox”>
<h5><?php the_time(‘j’); ?></h5>
<hr>
<h6><?php the_time(‘M’); ?></h6>
<h6><?php the_date(‘Y’); ?></h6>
</div>
</div>
</div>
<div class=”row infobox”>
<div class=”col-9″>
<h3><a href=”<?php the_permalink(); ?>”><?php the_category($separator = ‘, ‘); ?></a></h3>
<h4><a href=”<?php the_permalink(); ?>”><?php the_title(); ?></a></h4>
</div>
<div class=”col-3 infobox-moreinfo”>
<img src=”more_info.png”>
</div>
</div>
</div>
<?php endforeach; wp_reset_postdata(); } ?>

Here is the shortcode that, while displays something similar on the page, does not retrieve the blog posts themselves.

add_shortcode(‘home_blog’, function(){
ob_start();
?>
<?php $lastposts = get_posts( array(‘posts_per_page’ => 3) );?>
<?php if ( $lastposts ) {
foreach ( $lastposts as $post ) :
setup_postdata( $post ); ?>
<div class=”single_post” onclick=”location.href = ‘<?php the_permalink(); ?>’;”>
<div class=”postbox” style=”background-image: url(‘<?php echo catch_first_image() ?>’);”>
<div class=”pink_cover”>
<div class=”text-center datebox”>
<h5><?php the_time(‘j’); ?></h5>
<hr>
<h6><?php the_time(‘M’); ?></h6>
<h6><?php the_date(‘Y’); ?></h6>
</div>
</div>
</div>
<div class=”row infobox”>
<div class=”col-9″>
<h3><a href=”<?php the_permalink(); ?>”><?php the_category($separator = ‘, ‘); ?></a></h3>
<h4><a href=”<?php the_permalink(); ?>”><?php the_title(); ?></a></h4>
</div>
<div class=”col-3 infobox-moreinfo”>
<img src=”more_info.png”>
</div>
</div>
</div>
<?php endforeach; wp_reset_postdata(); } ?>
<?php
$output = ob_get_clean();
return $output;
});

Read more here:: get_posts works in the page template but not in a shortcode

Leave a Reply

Your email address will not be published. Required fields are marked *