Using “setup_postdata” with “get_template_part” does not work

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