Shortcodes need to return
their values, but the_content()
echo
es the post content.
So you have two options. First is to capture all output and then return it at the end:
ob_start(); // Start capturing output;
while( $loop->have_posts() ) {
$loop->the_post();
the_content();
};
wp_reset_postdata();
return ob_get_clean(); // Return captured output;
That will be the cleanest way if you want to capture HTML and the output of template tags or partials.
The other option is to get the content into a variable. The ‘get’ equivalent of the_content()
is get_the_content()
, but it tries weird stuff with the ‘Read More’ tag etc. so the easiest way is to get the raw $post->post_content
with the the_content
filters applied:
global $post;
// etc. etc.
while( $loop->have_posts() ) {
$loop->the_post();
$content = apply_filters( 'the_content', $post->post_content );
};
wp_reset_postdata();
return $content;
Also note how instead of return
ing inside the loop I put the value in a variable and returned it at the end. This is because if you return earlier in the function then wp_reset_postdata()
will never run, which could cause trouble with other loops on the page.