web-dev-qa-db-ja.com

(have_posts())、while(have_posts())が足りないのであれば、どうしていいのでしょうか。

「ループ」について質問があります。

<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<?php endwhile; else: ?>
<p><?php _e('Sorry, no posts matched your criteria.'); ?></p>
<?php endif; ?>

Loop WordPress Codexページから取得したコード

なぜifの部分を入れるべきなのですか? whileループがあれば、うまくいきます。

ifステートメントがないと、どのような場合に問題が発生しますか?

編集する

@ Chipの回答を受け入れました。正直言って私は最後の部分だけが必要だと言っています。

質問から知りたいことがわかりました。

ifステートメントは、一度だけ書くべきヘッダーやフッターを入れたい場合に必要なときだけです。 "wrapper"を使わないのなら、ifステートメントは必要ありません。

21
ironsand

WordPressテンプレートローダーには、多くの場合、そのコンテキストのクエリが投稿を返さない場合でも、適切なコンテキストテンプレートファイルが含まれます。例えば:

  • メインのブログ投稿インデックス
  • カテゴリアーカイブインデックス(カテゴリは存在しますが、投稿はありません)
  • タグアーカイブインデックス(タグは存在しますが、投稿はありません)
  • 著者アーカイブインデックス(著者は存在しますが、投稿はありません)
  • 検索結果インデックス

したがって、これらの場合、適切なテンプレートファイルが読み込まれますが、クエリは投稿を返さないため、投稿は出力されません。

概念実証の例:

そのため、これらのコンテキストでは、テンプレートファイルにif ( have_posts() )条件を含めると便利です。

他のコンテキストでは、クエリが投稿を返さない場合、テンプレートファイルはロードされません。例えば:

  • 単一のブログ投稿
  • 静的ページ

これらのコンテキストでは、if ( have_posts() )はおそらく不要です。

編集

クエリはthe_post()によって呼び出されることを理解していますか?また、while(have_posts())が存在する場合、投稿がないとクエリは発生しません。

何が起こっているのかを理解するには、 WordPressアクションの順序を確認する必要がありますwp_loadedで始まる(そして明確にするためにいくつかを省略する):

  • wp_loaded
  • parse_request
  • send_headers
  • parse_query
  • pre_get_posts
  • wp
  • template_redirect
  • get_header
  • wp_head
  • the_post
  • wp_footer

それで、何が起こって、どのような順序で?

  • クエリが呼び出されます:
    • parse_query
    • pre_get_posts
    • wp
  • テンプレートが選択されています:
    • template_redirect
  • テンプレートがロード/出力されます。次のアクションが実行されますテンプレートにより
    • get_header
    • wp_head
    • the_post
    • dynamic_sidebar
    • get_footer
    • wp_footer

したがって、the_post()によって起動されるthe_postが発生しますかなり後クエリが解析され、投稿がフェッチされ、テンプレートがロードされます。

私が知らなかった多くの情報を与えてくれたことにとても感謝していますが、これは私が尋ねたものではありません。

ああ、でもそれは正確にあなたが尋ねたものだと信じています。

本当の質問は:有効なクエリの戻り値は何ですか?カテゴリアーカイブインデックスなどのコンテキストの場合、クエリは有効で、クエリされたカテゴリIDが存在する場合、カテゴリテンプレートが読み込まれますそのカテゴリに割り当てられた投稿がない場合でも

どうして?解析されているクエリは(IIRC)&cat={ID}-有効なクエリそのカテゴリに投稿が割り当てられていない場合でもであり、解析時に404にならないためです。

その場合、有効なクエリを取得し、テンプレートファイルをロードしますしかし、投稿はありません。したがって、if ( have_posts() )は、実際には関連しています。繰り返しますが、ここに例があります。 カテゴリは存在しますが、投稿が割り当てられていません。カテゴリテンプレートファイルが読み込まれ、if ( have_posts() )false を返します。

これは、単一のブログ投稿や静的ページなどのpost変数(&p={ID})を含むクエリには当てはまりません。これは、投稿が実際には存在せず、解析時にクエリが有効なオブジェクトを返さないためです。

編集2

カテゴリテンプレートにif(have_posts())がなく、カテゴリに投稿がない場合、私が正しく理解している場合、投稿なしでcategory-sample.phpを返す必要がありますが、404.phpを返します。そうですか?

いいえ。テンプレートはtemplate_redirectで選択されています。クエリが有効であれば、適切なテンプレートファイルがロードされます。クエリが無効な場合、404テンプレートがロードされます。

したがって、テンプレートがロードされると-例えばカテゴリテンプレート-ループが出力されると、テンプレートは変更されません

アクションの順序をもう一度見てください。

  • parse_query
  • pre_get_posts
  • wp
  • template_redirect-テンプレートが選択され、ここにロードされます。これはテンプレートですリターンのないポイント。この時点以降、テンプレートは変更できません。
  • ...
  • the_post-ループ呼び出しの一部として、ここでpostdataが設定されます。これはテンプレート内、およびテンプレートは変更されませんクエリオブジェクトで利用可能なデータに基づいて呼び出されます

最終編集

そして、投稿の存在を確認しながら、同じテストを2回実行する必要があると主張しています。それは最初の点から私がそれについてだけ尋ねてきた私の質問です。

そして、これでようやく理解できました。ずっと、あなたの質問はWordPress、またはWordPressループとは何の関係もありませんでした。同じ条件をチェックするwhile条件内に任意のPHP ifループをラップすることを求めています。

この質問はWPSEの範囲外ですが、簡単に説明します。

if条件はバイナリ評価です。それはtrueまたはfalseのいずれかであり、その条件のinsideは実行されますonce

while条件はループです。ある種のカウンターに基づいて、離散期間の間はtrueのままです。そして、その条件のinsideが実行される数回-カウンターの各反復に対して1回.

そのため、物のリストにデータが入力されている場合、物の順序付けられていないリストを出力するとします。 whileループを使用し、ifラッパーを省略すると、マークアップは次のようになります。

<ul>
<?php while ( list_of_things() ) : ?>
    <li><?php the_list_item(); ?></li>
<?php endwhile; ?>
</ul>

_list_of_things()が空の場合、レンダリングされた出力は次のようになります。

<ul>
</ul>

不要な(そして無効な)マークアップが残ります。

しかし、if条件付きラッパーを追加する場合、これを行うことができます。

<?php if ( list_of_things() ) : ?>
    <ul>
    <?php while ( list_of_things() ) : ?>
        <li><?php the_list_item(); ?></li>
    <?php endwhile; ?>
    </ul>
<?php endif; ?>

_list_of_things()が空の場合、マークアップはまったく出力されません。

それはほんの一例です。そのif条件付きラッパーには多くの用途があり、if条件付きラッパーは、whileループよりもまったく異なる目的を提供します。

26
Chip Bennett

Chipの答えを改善することは本当に不可能ですが、追いかけないようにするだけです。

no posts があるときに何か別のものを表示させたい場合はif部分を使用してください。これは、たとえば日付やカテゴリのアーカイブページで特に便利です。誰かが投稿のないページに移動した場合、ループが実行されることはないので、まったく何も表示されないのではなく、そう言うメッセージがあると便利です。

if ( have_posts() ):
  // Yep, we have posts, so let's loop through them.
  while ( have_posts() ) : the_post();
  // do your loop
  endwhile;
else :
  // No, we don't have any posts, so maybe we display a Nice message
  echo "<p class='no-posts'>" . __( "Sorry, there are no posts at this time." ) . "</p>";
endif;
8
Tom Auger