web-dev-qa-db-ja.com

forループのget_template_part

私のテンプレート(およびレイアウト)の設定により、4つの異なる投稿に4つの異なる投稿を配置できるようにする必要があります。

たとえば、私の構造は次のようになります

<div>Post 1</div>
<div>
    <div>Post 2</div>
    <div>
        <div>Post 3</div>
        <div>Post 4</div>
    </div>
</div>

しかし、これを機能させるのに問題があります。最新の4つの投稿を取得するにはget_postsを使用します。

$posts = get_posts(array(
    'post_type' => 'post',
    'post_count' => 4
));  

それから私は自分の投稿を表示しようとします

<?php setup_postdata($posts[0]); ?>
<?php get_template_part( 'template-parts/post-thumbnail' ); ?>
<?php wp_reset_postdata(); ?>

template-parts/post-thumbnail.phpでは、タイトルとパーマリンクを表示しようとしていますが、常に現在のページのタイトルとリンクを表示しています。実際の投稿はありません。

4
woutr_be

あなたの問題は、setup_postdata() must に渡される変数が、次のようにグローバルな$post変数であることです。

// Reference global $post variable.
global $post;

// Get posts.
$posts = get_posts(array(
    'post_type' => 'post',
    'post_count' => 4
));  

// Set global post variable to first post.
$post = $posts[0];

// Setup post data.
setup_postdata( $post );

// Output template part.
get_template_part( 'template-parts/post-thumbnail' );

// Reset post data.
wp_reset_postdata();

テンプレート部分内のthe_post_thumbnail()のような通常のテンプレート関数は正しい投稿を参照するようになりました。

6
Jacob Peattie

get_template_part() を使用している場合、$ postsはpost-thumbnail.phpのコンテキスト内では使用できないため、現在のページで見つかった投稿IDが使用されます。変数を利用できるようにするには locate_template() を使用する必要があります。これは、get_template_partが内部的に使用するものです。

<?php $posts = get_posts( array( 'post_type' => 'post', 'post_count' => 4 ) ); ?>

<?php foreach ( $posts as $post ) : setup_postdata( $post ); ?>
    <?php locate_template( 'page-templates/post-thumbnail.php', true, false ); ?>
<?php endforeach; wp_reset_postdata(); ?>

そうすれば、正しい投稿データを持つpage-templates/post-thumbnail.phpテンプレートにあるものすべてを持つことができます。

<div>
    <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
</div>
3
Tim Elsass

グローバルをめちゃくちゃにする以外に、テンプレート部分を機能させるために余分な作業をまったく必要としないカスタムループを作成できます。例えば:

$args = array(
    'post_type' => 'post',
    'posts_per_page' => 4
);

$my_query = new WP_Query($args);
if ($my_query->have_posts()){
    while ($my_query->have_posts()){
        $my_query->the_post(); // This is where the post's data is set up
        get_template_part( 'template-parts/post-thumbnail' );
    }
}

完了しました。ループ内の各投稿に対して投稿のデータを設定する必要はありません。

ちなみに get_posts() 自体は投稿を取得するためにWP_Query()を使用しますが、違いはそれがあなたのために投稿のデータを設定しないということです、そしてそれはループの後にリセットされる必要があります。

3
Jack Johansson

あなたの地方に持っていこう

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

wp_reset_postdata は現在のクエリの結果をリセットするのに重要です。

2
While1