ループの詳細

基本的なループは:

  1. <?php
  2. if ( have_posts() ) :
  3. while ( have_posts() ) : the_post();
  4. // Display post content
  5. endwhile;
  6. endif;
  7. ?>

このループは、投稿がある場合にそれらをループして表示することを示しています。詳細に分解すると:

  • have_posts() 関数は、投稿があるかどうかを確認します。
  • 投稿がある場合、while ループは、括弧内の条件が論理的に真である限り実行され続けます。have_posts() が真である限り、ループは続きます。

ループの使用

ループは index.php に配置する必要があり、投稿情報を表示するために使用される他のテンプレートにも配置する必要があります。ヘッダーを何度も重複させたくないため、ループは常に get_header() の呼び出しの後に配置する必要があります。例えば:

  1. <?php
  2. get_header();
  3. if ( have_posts() ) :
  4. while ( have_posts() ) : the_post();
  5. // Display post content
  6. endwhile;
  7. endif;
  8. ?>

上記の例では、ループの終わりは endwhileendif で示されています。ループは常に上記のように同じ ifwhile ステートメントで始まり、同じ終了ステートメントで終わる必要があります。

すべての テンプレートタグ は、開始と終了のステートメントの間に存在する必要があります。

指定された条件に一致する投稿がない場合に表示されるカスタム404「見つかりません」メッセージを含めることができます。このメッセージは、以下の例に示すように endwhileendif ステートメントの間に配置する必要があります。

非常にシンプルな index.php ファイルは次のようになります:

  1. <?php
  2. get_header();
  3. if ( have_posts() ) :
  4. while ( have_posts() ) : the_post();
  5. the_content();
  6. endwhile;
  7. else :
  8. _e( 'Sorry, no posts matched your criteria.', 'textdomain' );
  9. endif;
  10. get_sidebar();
  11. get_footer();
  12. ?>

ループが表示できるもの

ループは、各投稿のさまざまな要素を表示できます。例えば、多くのテーマで使用される一般的な テンプレートタグ は次のとおりです:

  • next_post_link() – 現在の投稿の後に時系列で公開された投稿へのリンク
  • previous_post_link() – 現在の投稿の前に時系列で公開された投稿へのリンク
  • the_category() – 表示されている投稿またはページに関連付けられたカテゴリ
  • the_author() – 投稿またはページの著者
  • the_content() – 投稿またはページの主要なコンテンツ
  • the_excerpt() – 投稿の主要なコンテンツの最初の55語の後に省略記号(…)または全文へのリンクが続きます。また、投稿の「抜粋」フィールドを使用して特定の抜粋の長さをカスタマイズすることもできます。
  • the_ID() – 投稿またはページのID
  • the_meta() – 投稿またはページに関連付けられたカスタムフィールド
  • the_shortlink() – サイトのURLと投稿またはページのIDを使用してページまたは投稿へのリンク
  • the_tags() – 投稿に関連付けられたタグ
  • the_title() – 投稿またはページのタイトル
  • the_time() – 投稿またはページの時間または日付。これは、標準のphp日付関数のフォーマットを使用してカスタマイズできます。

また、次のような 条件タグ を使用することもできます:

  • is_home() – 現在のページがホームページである場合は真を返します
  • is_admin() – 管理画面内にいる場合は真を返し、それ以外は偽を返します
  • is_single() – 現在のページが単一の投稿を表示している場合は真を返します
  • is_page() – 現在のページが単一のページを表示している場合は真を返します
  • is_page_template() – ページが特定のテンプレートを使用しているかどうかを判断するために使用できます。例えば: is_page_template('about-page.php')
  • is_category() – ページまたは投稿が指定されたカテゴリを持っている場合は真を返します。例えば: is_category('news')
  • is_tag() – ページまたは投稿が指定されたタグを持っている場合は真を返します
  • is_author() – 著者のアーカイブページ内にいる場合は真を返します
  • is_search() – 現在のページが検索結果ページである場合は真を返します
  • is_404() – 現在のページが存在しない場合は真を返します
  • has_excerpt() – 投稿またはページに抜粋がある場合は真を返します

ループの動作のいくつかの例を見てみましょう:

基本的な例

ブログアーカイブ

ほとんどのブログにはブログアーカイブページがあり、投稿のタイトル、サムネイル、抜粋などを表示できます。以下の例は、投稿があるかどうかを確認し、ある場合は各投稿のタイトル、サムネイル、抜粋を出力するシンプルなループを示しています。投稿が存在しない場合は、括弧内のメッセージが表示されます。

  1. <?php
  2. if ( have_posts() ) :
  3. while ( have_posts() ) : the_post();
  4. the_title( '<h2>', '</h2>' );
  5. the_post_thumbnail();
  6. the_excerpt();
  7. endwhile;
  8. else:
  9. _e( 'Sorry, no posts matched your criteria.', 'textdomain' );
  10. endif;
  11. ?>

個別投稿

WordPressでは、各投稿にはその投稿に関連する情報を表示する独自のページがあります。テンプレートタグを使用すると、表示したい情報をカスタマイズできます。

以下の例では、ループが投稿のタイトルとコンテンツを出力します。この例を投稿またはページのテンプレートファイルで使用して、投稿に関する最も基本的な情報を表示できます。また、このテンプレートをカスタマイズして、投稿にカテゴリなどの追加データを追加することもできます。

  1. <?php
  2. if ( have_posts() ) :
  3. while ( have_posts() ) : the_post();
  4. the_title( '<h1>', '</h1>' );
  5. the_content();
  6. endwhile;
  7. else:
  8. _e( 'Sorry, no pages matched your criteria.', 'textdomain' );
  9. endif;
  10. ?>

中級例

特定のカテゴリの投稿を異なるスタイルで表示

以下の例では、いくつかのことを行います:

  • まず、各投稿をそのタイトル、時間、著者、コンテンツ、カテゴリとともに表示します。これは上記の個別投稿の例に似ています。
  • 次に、カテゴリIDが「3」の投稿を異なるスタイルで表示できるように、in_category() テンプレートタグを利用します。

この例のコードコメントは、ループの各段階での詳細を提供します:

  1. <?php
  2. // Start the Loop.
  3. if ( have_posts() ) :
  4. while ( have_posts() ) : the_post();
  5. /* * See if the current post is in category 3.
  6. * If it is, the div is given the CSS class "post-category-three".
  7. * Otherwise, the div is given the CSS class "post".
  8. */
  9. if ( in_category( 3 ) ) : ?>
  10. <div class="post-category-three">
  11. <?php else : ?>
  12. <div class="post">
  13. <?php endif;
  14. // Display the post's title.
  15. the_title( '<h2>', ';</h2>' );
  16. // Display a link to other posts by this posts author.
  17. printf( __( 'Posted by %s', 'textdomain' ), get_the_author_posts_link() );
  18. // Display the post's content in a div.
  19. ?>
  20. <div class="entry">
  21. <?php the_content() ?>
  22. </div>
  23. <?php
  24. // Display a comma separated list of the post's categories.
  25. _e( 'Posted in ', 'textdomain' ); the_category( ', ' );
  26. // closes the first div box with the class of "post" or "post-cat-three"
  27. ?>
  28. </div>
  29. <?php
  30. // Stop the Loop, but allow for a "if not posts" situation
  31. endwhile;
  32. else :
  33. /*
  34. * The very first "if" tested to see if there were any posts to
  35. * display. This "else" part tells what do if there weren't any.
  36. */
  37. _e( 'Sorry, no posts matched your criteria.', 'textdomain' );
  38. // Completely stop the Loop.
  39. endif;
  40. ?>

複数のループ

場合によっては、複数のループを使用する必要があります。例えば、ページの上部に目次リストで投稿のタイトルを表示し、その後ページの下部でコンテンツを表示したい場合があります。クエリが変更されないため、投稿を2回ループする必要があるときは、単にループを巻き戻す必要があります。そのために、rewind_posts() 関数を使用します。

rewind_postsの使用

rewind_posts() を使用して、同じ クエリを2回ループすることができます。これは、ページの異なる場所で同じクエリを2回表示したい場合に便利です。

以下は rewind_posts() の使用例です:

  1. <?php
  2. // Start the main loop
  3. if ( have_posts() ) :
  4. while ( have_posts() ) : the_post();
  5. the_title();
  6. endwhile;
  7. endif;
  8. // Use rewind_posts() to use the query a second time.
  9. rewind_posts();
  10. // Start a new loop
  11. while ( have_posts() ) : the_post();
  12. the_content();
  13. endwhile;
  14. ?>

二次クエリとループの作成

同じクエリを使用して2つのループを使用するのは比較的簡単ですが、常に必要なわけではありません。代わりに、テンプレートで異なるコンテンツを表示するために二次クエリを作成したいことがよくあります。例えば、同じページに2つの投稿グループを表示したいが、それぞれのグループに異なる操作を行いたい場合があります。以下に示す一般的な例は、単一の投稿の下に同じカテゴリの投稿のリストを表示することです。

  1. <?php
  2. // The main query.
  3. if ( have_posts() ) :
  4. while ( have_posts() ) : the_post();
  5. the_title();
  6. the_content();
  7. endwhile;
  8. else :
  9. // When no posts are found, output this text.
  10. _e( 'Sorry, no posts matched your criteria.' );
  11. endif;
  12. wp_reset_postdata();
  13. /*
  14. * The secondary query. Note that you can use any category name here. In our example,
  15. * we use "example-category".
  16. */
  17. $secondary_query = new WP_Query( 'category_name=example-category' );
  18. // The second loop.
  19. if ( $secondary_query->have_posts() )
  20. echo '<ul>';
  21. while ( $secondary_query->have_posts() ) : $secondary_query->the_post();
  22. the_title( '<li>', '</li>' );
  23. endwhile;
  24. echo '</ul>';
  25. endif;
  26. wp_reset_postdata();
  27. ?>

上記の例では、最初に通常のループを表示します。次に、WP_Query を使用して特定のカテゴリをクエリする新しい変数を定義します。この場合、example-category スラッグを選択しました。

上記の例の通常のループには1つの違いがあります: wp_reset_postdata() を呼び出して投稿データをリセットします。二次ループを使用する前に、投稿データをリセットする必要があります。これを行う方法は2つあります:

  • 1. rewind_posts() 関数を使用すること; または
  • 2. 新しいクエリオブジェクトを作成すること。

複数のループのリセット

テンプレートで複数のループを使用する際は、それらをリセットすることが重要です。リセットしないと、グローバル $post 変数内でデータがどのように保存され、使用されるかによって予期しない結果が生じる可能性があります。呼び出し方によってループをリセットする主な方法は3つあります。

  • wp_reset_postdata()
  • wp_reset_query()
  • rewind_posts()

wp_reset_postdataの使用

wp_reset_postdata() を使用して、WP_Query でカスタムまたは複数のループを実行しているときに使用します。この関数は、グローバル $post 変数をメインクエリの現在の投稿に復元します。ベストプラクティスに従っている場合、これはループをリセットするために最も一般的に使用される関数です。

この関数を正しく使用するには、WP_Query を使用したループの後に次のコードを配置します:

  1. <?php wp_reset_postdata(); ?>

以下は、WP_Query を使用してループを作成し、wp_reset_postdata() でリセットされる例です。

  1. <?php
  2. // Example argument that defines three posts per page.
  3. $args = array( 'posts_per_page' => 3 );
  4. // Variable to call WP_Query.
  5. $the_query = new WP_Query( $args );
  6. if ( $the_query->have_posts() ) :
  7. // Start the Loop
  8. while ( $the_query->have_posts() ) : $the_query->the_post();
  9. the_title();
  10. the_excerpt();
  11. // End the Loop
  12. endwhile;
  13. else:
  14. // If no posts match this query, output this text.
  15. _e( 'Sorry, no posts matched your criteria.', 'textdomain' );
  16. endif;
  17. wp_reset_postdata();
  18. ?>

wp_reset_queryの使用

wp_reset_query() を使用すると、WP_Query とグローバル $post データが元のメインクエリに復元されます。ループ内で query_posts() を使用する場合は、この関数を使用してループをリセットする必要があります。カスタムループで WP_Query を使用した後に使用できます。なぜなら、実際に実行時に wp_reset_postdata() を呼び出すからです。しかし、wp_reset_postdata() を使用することがベストプラクティスです。query_posts()ベストプラクティスではなく、可能な限り避けるべきです。したがって、wp_reset_query() を使用する必要はあまりありません。

この関数を正しく使用するには、query_posts() を使用したループの後に次のコードを配置します。

  1. <?php wp_reset_query(); ?>