It looks like your code example is taken from inside a function.
a) Please try this:
// ... cut ... global $post; $args = array( 'posts_per_page' => 6, 'orderby' => 'post_date' ); $postslist = get_posts( $args ); $content .= '<div class="tab" id="new"><ul>'; foreach ( $postslist as $post ) : setup_postdata( $post ); $content .= sprintf( '<li><a href="%s">%s</a></li>', get_permalink(), get_the_title() ); endforeach; $content .= '</ul></div>'; wp_reset_postdata(); return $content; // prints all the contents stringed together
where I added the global $post declaration so setup_postdata( $post ) can modify the global $post object.
b) Or try this:
// ... cut ... $args = array( 'posts_per_page' => 6, 'orderby' => 'post_date' ); $postslist = get_posts( $args ); $content .= '<div class="tab" id="new"><ul>'; foreach ( $postslist as $post ) : $content .= sprintf( '<li><a href="%s">%s</a></li>', get_permalink( $post->ID ), get_the_title( $post->ID ) ); endforeach; $content .= '</ul></div>'; return $content; // prints all the contents stringed together
where I used the post id as an input argument for get_permalink() and get_the_title().
c) You can also use the raw post title: $post->post_title or if you want to take it through the the_title filter with:
echo apply_filters( 'the_title', $post->post_title );
So to wrap it up:
Notice that get_the_title() is based on get_post(), and if you don't use an input argument, then it will try to use the global $post object:
if ( empty( $post ) && isset( $GLOBALS['post'] ) ) $post = $GLOBALS['post'];
Therefore you always get the same global post object title (usually from the main query) if you don't modify the global object within the secondary loop.
Hope this helps.
get_posts()for 6 things, it gave you 6 things. It looks like it is up to you to check for duplicates.