I've used the second-last example showed here: https://github.com/scribu/wp-posts-to-posts/wiki/each_connected

The only difference is that I've put the_title after echoing the connected posts. So my code is:

$my_query = new WP_Query( array(
    'post_type' => 'movie'
) );

p2p_type( 'movies_to_actors' )->each_connected( $my_query, array(), 'actors' );

p2p_type( 'movies_to_locations' )->each_connected( $my_query, array(), 'locations' );

while ( $my_query->have_posts() ) : $my_query->the_post(); ?>

    // Display connected actors
    echo '<p>Actors:</p>';

    foreach ( $post->actors as $post ) : setup_postdata( $post );



    // Display connected locations
    echo '<p>Filming locations:</p>';

    foreach ( $post->locations as $post ) : setup_postdata( $post );



    <?php the_title(); ?>

<?php endwhile; ?>

The problem is that all the posts show me the title of the first post:

Actors: actors of post title n.1

Locations: locations of post title n.1


Actors: actors of post title n.2

Locations: locations of post title n.2

TITLE n.1 <<<--- WRONG!!!

2 Answers 2


wp_reset_postdata() restores the post from main query, which you do not seem to be using here at all. So before final the_title() call you jump out all the way to that post.

Your code seems to be tad problematic to me because both your outer and inner loops continuously rewrite $post global. If you move away from that in inner loops (by using versions of functions that take post/id to act on) you will likely escape multiple overrides/resets and issues like that.

Something like this:

while ( $my_query->have_posts() ) : $my_query->the_post();

    foreach ( $post->actors as $actor ) :

        echo get_the_title( $actor );


  • Hi Rarst, thank you very much for the answer. Isn't the while at the 10th row the main query? Moreover, I've tried to use another variable in opposite to $post inside the two foreach, but it didn't affect the_title() inside them, so I've leave the $post variable. How can I rewrite the code in order to make it to work in your opinion? Jun 10, 2013 at 15:41
  • @MarcoPanichi nope, what WP considers main query is held in global $wp_query variable and set up before you even reach template. What you have are two levels of secondary queries.
    – Rarst
    Jun 10, 2013 at 15:44
  • Ok! I understood. So I have to find a way to reset my post data to the first secondary level of that queries. You are talking about functions to move away from the inner loops: it could be a solution. What functions are you talking about? Jun 10, 2013 at 15:46
  • @MarcoPanichi I have added code example to the answer
    – Rarst
    Jun 10, 2013 at 15:47
  • I was afraid that functions like get_the_title() (not used on the same post inside a loop) were performing some queries on the database (and it could be a problem because I have more than one entities connected and lots of posts). So I didn't tried. Instead I've checked the code discovering that the function has nothing to do with database. I'll try instantly. Jun 10, 2013 at 15:59

You actually need to globalize $post in your code for setup_postdata() to do the right thing. It's a bit of a gotcha, as setup_postdata() merely sets up the related globals ($id, $authordata, $currentday, $currentmonth, $page, $pages, $multipage, $more, $numpages) but doesn't populate the global $post object, from which the_title() pulls the title.

Solution: global $post; before your loop.

In your case, wp_reset_postdata() isn't really necessary since you're never actually using the data from the main query, only the subqueries.

  • Thank you for your reply @Bendoh. I've tried to add the globalization before the loop and then inside the two foreach but it doesn't work. Maybe because, as Rarst said, I'm using the $post variable inside the foreach Jun 10, 2013 at 16:04

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.