web-dev-qa-db-ja.com

Wp_reset_postdata()が最初の投稿からループを再開するのはなぜですか?

ここに示した最後から2番目の例を使用しました。 https://github.com/scribu/wp-posts-to-posts/wiki/each_connected

唯一の違いは、接続された投稿をエコーし​​た後にthe_titleを付けたことです。だから私のコードは:

<?php
$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(); ?>

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

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

        ...
    endforeach;

    wp_reset_postdata();

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

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

        ...
    endforeach;

    wp_reset_postdata();
    ?>

    <?php the_title(); ?>

<?php endwhile; ?>

問題は、すべての投稿に最初の投稿のタイトルが表示されることです。


役者:役職n.1の役者

場所:役職n.1の場所

タイトルn.1


役者:役職n.2の役者

場所:役職n.2の場所

タイトルn.1<<< ---間違っています!!!

1
Marco Panichi

wp_reset_postdata()メインクエリから投稿を復元しますが、ここではまったく使用していないようです。それで、最後のthe_title()呼び出しの前に、あなたはその投稿までずっと飛び出します。

あなたのコードは私にとっては少し問題があるように思われます。あなたの外側と内側の両方のループが継続的に$post globalを書き換えるからです。内側のループでそれから離れると(post/idを有効にする関数のバージョンを使用することによって)、複数のオーバーライド/リセットとそのような問題を回避する可能性があります。

このようなもの:

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

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

        echo get_the_title( $actor );

    endforeach;

endwhile;
1
Rarst

setup_postdata()が正しいことをするためには、実際にはコードの中で$postをグローバル化する必要があります。 setup_postdata()は単に関連グローバル($id, $authordata, $currentday, $currentmonth, $page, $pages, $multipage, $more, $numpages)を設定するが、グローバルな$postオブジェクトを生成しないので、ちょっとした落とし穴です。そこからthe_title()はタイトルを取得します。

解決策:ループの前にglobal $post;を付けてください。

あなたの場合、wp_reset_postdata()は実際には必要ありません。なぜならあなたは実際にはメインクエリからのデータを使用するのではなく、サブクエリのみを使用するからです。

0
Bendoh