I want to reuse code made in a template in a shortcode.

I did this in my shortcode

$args = array(...);             
$posts      = get_posts($args);
for ( $j=0; $j < count($posts); $j++ ) {

    $post_id = $posts[$j]->ID;


    get_template_part( 'includes/post-formats/postbox' );
    $output .= ob_get_contents();

return $output;

Code in the template is something like this:

<div class="post-header span3">
        <?php if(is_sticky()) : ?>
            <h5 class="post-label"><?php echo theme_locals("featured");?></h5>
        <?php endif; ?>
        <h2 class="post-title"><a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>"><?php the_title(); ?></a></h2>
            the_post_thumbnail( 'medium' );
 <div class="foo">
 <?php the_content(); ?>

Well, the problem is that the title and the thumbnail don't work, the title and the thumbnail are shown wrong. Only the content is shown well (via the_content()).

  • 3
    You have to use the $post global. setup_postdata( $post ) Jun 29, 2015 at 17:44
  • 1
    If I'm not mistaken, it's probably a good idea to run wp_reset_postdata(); after your loop since you're using setup_postdata() function.
    – Howdy_McGee
    Jun 29, 2015 at 17:58
  • @Howdy_McGee you are correct. setup_postdata changes the global $post value to the current value of the custom loop. You must reset your $post global back to main query ;-) Jun 29, 2015 at 18:14
  • My pleasure, enjoy ;-) Jun 30, 2015 at 6:46
  • 1
    Related: stackoverflow.com/questions/39101020/… May 6, 2018 at 4:04

1 Answer 1


For those who aren't creating a query with get_posts() you may need to reference the global $post variable first before using setup_postdata().

Here is an example shortcode using a foreach loop and iterating through an array of post objects from an ACF Relationship field:

function your_shortcode() {
    //reference global $post first
    global $post;

    $featured_posts = get_field('relationship_field'); 
    $html = '';


    foreach( $featured_posts as $post ): 

        // Setup this post for WP functions (variable must be named $post).

        get_template_part('php/components/card', 'project');


    $html .= ob_get_clean();

    // Reset the global post object so that the rest of the page works correctly.

    return $html;

add_shortcode( 'your-shortcode', 'your_shortcode' );

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.