0

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;
});
2
  • 1
    You might be missing global $post before the foreach loop in your shortcode function. Please refer to the setup_postdata codex entry, codex.wordpress.org/Function_Reference/setup_postdata Oct 25, 2018 at 10:57
  • @AnttiKoskinen, you're a genius :) That was it! Thanks, man! If you want to write that as an answer, then I'll mark it as correct. :) Oct 25, 2018 at 10:59

1 Answer 1

2

You might be missing global $post before the foreach loop in your shortcode function. Please refer to the setup_postdata codex entry.

Your Answer

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

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