I know this has been answered and the answer solved the issue but I found it very poor for any newbie that want to learn WordPress so I give mine in the hope it will be better:
- While
get_posts()
can do the job I would have used a simple
query, for a secondary loop I prefer creating my own separate
instance of the WP_Query - Engelen is right there’s no use for
wp_reset_postdata()
here - The use of
$content
is also unecessary here, it’s not a enclosing shortcode - A shortcode returns something. On no account it should output something on its own. That could trigger unpredictable bugs. It’s quite the same with
add_filter()
- I know here it’s just for test but generic names must be avoided for shortcodes because there is only one hook per shortcode so any shortcode that use the same name could override leading to unexpected results.
So for all these reasons I would recommand to do this instead :
add_shortcode( 'post_title', 'wpse_149667_post_title_sc' );
function wpse_149667_post_title_sc( $atts ){
$args = array( 'posts_per_page' => 3 );
$lastposts = new WP_Query( $args );
if( $lastposts->have_posts() ) :
$output="<ul>";
while( $lastposts->have_posts() ) : $lastposts->the_post();
$output .= '<li>'.get_the_title($lastposts->post->ID).'</li>';
endwhile;
$output .= '</ul>';
else :
$output="There is currently no post to retrieve!";
endif;
wp_reset_postdata();// more appropriate here
return $output;
}
Hope this gives more explanations.