templates - Using "setup_postdata" with "get_template_part" does not work

admin2025-01-07  3

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;

    setup_postdata($posts[$j]);
    ob_start();

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

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>
        <?php
            the_post_thumbnail( 'medium' );
        ?>
    </div>
 <div class="foo">
 <?php the_content(); ?>
 </div>

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()).

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;

    setup_postdata($posts[$j]);
    ob_start();

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

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>
        <?php
            the_post_thumbnail( 'medium' );
        ?>
    </div>
 <div class="foo">
 <?php the_content(); ?>
 </div>

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()).

Share Improve this question edited Jun 30, 2015 at 6:43 dlopezgonzalez asked Jun 29, 2015 at 17:40 dlopezgonzalezdlopezgonzalez 1732 silver badges7 bronze badges 5
  • 3 You have to use the $post global. setup_postdata( $post ) – Pieter Goosen Commented 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 Commented 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 ;-) – Pieter Goosen Commented Jun 29, 2015 at 18:14
  • My pleasure, enjoy ;-) – Pieter Goosen Commented Jun 30, 2015 at 6:46
  • 1 Related: stackoverflow.com/questions/39101020/… – Luke Gedeon Commented May 6, 2018 at 4:04
Add a comment  | 

1 Answer 1

Reset to default 0

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 = '';

    ob_start();

    foreach( $featured_posts as $post ): 

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

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

    endforeach;

    $html .= ob_get_clean();

    // Reset the global post object so that the rest of the page works correctly.
    wp_reset_postdata(); 

    return $html;

}
add_shortcode( 'your-shortcode', 'your_shortcode' );
转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1736259069a561.html

最新回复(0)