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()).
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' );
$post
global.setup_postdata( $post )
– Pieter Goosen Commented Jun 29, 2015 at 17:44wp_reset_postdata();
after your loop since you're usingsetup_postdata()
function. – Howdy_McGee ♦ Commented Jun 29, 2015 at 17:58setup_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