I'm using get_posts() to fetch posts from a particular category to display at the top of my homepage, separate from the main homepage Loop. Everything seems to work fine, but for the title (returned through the_title()) which is always the same; the title of the first post fetched by get_posts(). the_permalink() does the same as well, but the_excerpt() returns the correct result for each post.

Here's my code (I have removed only a few lines for fear I might inadvertently remove what is causing this problem):

$query = get_posts(array(
$events = array();

if ($query) {
    foreach ($query as $tpost) {
        $fields = get_post_custom($tpost->ID);
        if (isset($fields['event_start'])) {
            $usetime = $fields['event_start'][0];
            if (isset($fields['event_end'])) {
                $usetime = $fields['event_end'][0];
            if ($usetime>time()) {
                $events[] = array("post"=>$tpost,"fields"=>$fields);
        $a = $a['fields']['event_start'][0];
        $b = $b['fields']['event_start'][0];
        if ($a==$b) { return 0; }
        return ($a < $b) ? -1 : 1;

if (count($events)>0) { ?>
    <div class="pad10 tac">
    <h2 class="mar10">Upcoming Events</h2>
    <div class="tiles">
    <?php foreach ($events as $event ) { ?>
        <?php setup_postdata( $event['post'] );?>
        <a href="<?php the_permalink(); ?>" class='noshow'>
        <div class="tile smalltile"><div id='post-<?php the_ID(); ?>'>
            <h2><?php the_title();?></h2>
            echo(date_i18n("D, F j @ g:ia",$event['fields']['event_start'][0]));
            <p><?php the_excerpt();?></p>
    <?php }?>
<?php }?>

I'm really scratching my head on this, especially as this code is, for the most part, based off of the get_posts() example from this article, where it is reportedly working fine.

I'm thinking that this likely has something to do with my use of setup_postdata, but I suppose this is really just wild speculation.

  • 1
    The Codex page for setup_postdata() explains why this doesn't work and how to fix it.
    – Milo
    Nov 21, 2016 at 5:56
  • 1
    @Milo Ah, of course, I should have realised. Thank you! Would you like to write this as an answer, so it can be accepted?
    – Laef
    Nov 21, 2016 at 6:59

2 Answers 2


Making Milos's comment into an answer....

The problem you are facing is the result of many wordpress template oriented functions expect some global variables. In WP_Query based loops setting those variable is done by calling the the_post() method of the WP_Query object, but with get_posts you need to call setup_postdata() for that.

My personal preference is to just try to avoid functions like the_title in favor of functions like get_the_title, that accept an explicit post id, whenever possible.


Use setup_postdata() for that.

Important setup_postdata() does not assign the global $post variable so it’s important that you do this yourself.

Important use wp_reset_postdata() after your foreach loop.

For more information visit: https://developer.wordpress.org/reference/functions/setup_postdata/

    // Get posts
    global $post;
    $posts = get_posts([
        'post_type' => 'post',
        'numberposts' => 6

<?php foreach ($posts as $key => $post): ?>
    <?php setup_postdata($post); ?>
        <a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>">
            <?php the_title(); ?>
<?php endforeach; ?>
<?php wp_reset_postdata(); ?>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.