web-dev-qa-db-fra.com

Pourquoi devrais-je mettre if (have_posts ()), est-ce que while (have_posts ()) ne suffit pas?

J'ai une question à propos de "la boucle".

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

Code extrait de La page Loop WordPress Codex .

Pourquoi devrais-je mettre if part? Il semble que s'il y a une boucle while, fonctionne bien.

Dans quel cas le problème se produit s'il n'y a pas d'instruction if?

Modifier

J'ai accepté la réponse de @ Chip. mais honnêtement, je n'ai besoin que de la dernière partie.

Je sais maintenant ce que je voulais savoir de ma question.

L'instruction if n'est nécessaire que si vous voulez mettre un en-tête ou un pied de page qui doit être écrit une seule fois. Si vous n'utilisez pas le "wrapper", l'instruction if n'est pas nécessaire.

21
ironsand

Le chargeur de modèles WordPress inclura le fichier de modèle contextuel approprié dans de nombreuses circonstances, même si la requête pour ce contexte ne renvoie aucune publication. Par exemple:

  • Les principaux articles du blog
  • Index des archives de la catégorie (la catégorie existe, mais n'a pas encore de post)
  • Index des archives de balises (la balise existe, mais n'a pas de message)
  • Index d'archives d'auteurs (l'auteur existe mais n'a pas posté)
  • Index des résultats de recherche

Ainsi, dans ces cas, le fichier de modèle approprié sera chargé, mais aucun article ne sera généré, car la requête ne renvoie aucun article.

Exemples de preuve de concept:

Ainsi, dans ces contextes, il est utile que le fichier de modèle inclue la condition if ( have_posts() ).

Dans d'autres contextes, le fichier de modèle ne sera jamais chargé si la requête ne renvoie aucun article. Par exemple:

  • Un seul blog
  • Page statique

Dans ces contextes, if ( have_posts() ) est probablement inutile.

Modifier

Je comprends que la requête est invoquée par the_post (), non? Et si while (have_posts ()) existe, la requête ne se produit jamais s'il n'y a pas de message.

Pour comprendre ce qui se passe, vous devez regarder l'ordre des actions WordPress . Commençant par wp_loadedet en omettant certaines pour plus de clarté):

Alors, que se passe-t-il et dans quel ordre?

Donc, the_post, déclenché par the_post(), se passe longtemps après la requête est analysée, les publications sont récupérées et le modèle est chargé.

Je suis très reconnaissant que vous donniez beaucoup d'informations que je ne connaissais pas, mais ce n'est pas ce que j'ai demandé.

Oh, mais je crois que c'est exactement ce que vous avez demandé.

La vraie question est: qu'est-ce qu'un retour de requête valide? Pour des contextes tels que l'index d'archivage des catégories, la requête est valide et le modèle de catégorie est chargé. Si l'ID de catégorie interrogé existe, même si aucune publication n'est affectée à cette catégorie.

Pourquoi? Parce que la requête en cours d'analyse est (IIRC) &cat={ID} - qui est une requête valide même si aucune publication n'est affectée à cette catégorie, et n'entraîne donc pas un 404 lors de l'analyse.

Dans ce cas, vous obtenez une requête valide et un fichier de modèle chargé, mais pas de publication. Ainsi, if ( have_posts() ), est en fait pertinent. Encore une fois, voici un exemple: _ (la catégorie existe, mais aucune publication n’a été attribuée. Le fichier de modèle de catégorie est chargé, avec if ( have_posts() ) retournant false .

Cela ne s'appliquera pas aux requêtes qui incluent une variable publication (&p={ID}), telles que les publications sur un seul blog et les pages statiques, car la publication n'existe pas et, lorsqu'elle est analysée, la requête ne renvoie pas objet valide.

Modifier 2

Si je comprends bien s'il n'y a pas de if (have_posts ()) dans un modèle de catégorie et si la catégorie n'a pas de publication, elle renvoie 404.php, même si elle doit renvoyer category-sample.php sans publication. Est-ce correct?

N ° Rappelez-vous: le modèle est sélectionné à template_redirect. Donc, si la requête est valide, le fichier de modèle approprié est chargé. Si la requête n'est pas valide, le modèle 404 est chargé.

Ainsi, une fois qu'un modèle est chargé - par ex. le modèle de catégorie - une fois la boucle générée, le modèle ne change pas.

Regardez encore l'ordre des actions:

  • parse_query
  • pre_get_posts
  • wp
  • template_redirect - template est choisi et chargé ici. Ceci est le template point de non retour. Le modèle ne peut pas changer après ce point.
  • ...
  • the_post - postdata est configuré ici, dans le cadre de l'appel en boucle. Ceci s'appelle à l'intérieur du modèle _ et le modèle ne change pas en fonction des données disponibles dans l'objet de requête.

Édition finale

Et je prétends que tout en vérifiant l'existence de messages, pourquoi devrais-je exécuter le même test deux fois. Telle est ma question depuis le premier point que je pose seulement à ce sujet.

Et avec ça, je comprends enfin: depuis toujours, votre question n’a rien à voir avec WordPress, ni le WordPress Loop. Vous posez la question de placer une boucle PHP while arbitraire dans une condition if vérifiant la même condition.

Cette question sort du cadre de WPSE, mais je vais expliquer brièvement:

Une if conditionnelle est une évaluation binaire: c'est soit true ou false, et ce qui se passe à l'intérieur de cette conditionnelle est exécuté une fois.

Une condition while est une boucle: elle reste vraie pour une période discrète, basée sur une sorte de compteur; et ce qui se passe à l'intérieur de ce conditionnel est exécuté plusieurs fois - une fois pour à chaque itération du compteur.

Supposons donc que vous souhaitiez générer une liste non ordonnée d'éléments, si cette liste est renseignée. Si vous utilisez une boucle while et omettez le wrapper if, votre balise ressemblerait à ceci:

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

Et si list_of_things() était vide, la sortie rendue serait:

<ul>
</ul>

Ce qui laisse un balisage inutile (et invalide).

Mais si vous ajoutez une enveloppe if conditionnelle, vous pouvez procéder comme suit:

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

Et si list_of_things() était vide, aucune annotation ne serait sortie.

Ce n'est qu'un exemple. Il existe de nombreuses utilisations pour cette enveloppe conditionnelle if, et cette enveloppe conditionnelle if sert une boucle {tout à fait différente} que la boucle while.

26
Chip Bennett

Il est vraiment impossible d'améliorer la réponse de Chip, mais juste pour aller droit au but:

Utilisez la partie if si vous voulez que quelque chose de différent apparaisse quand il n'y a pas de posts . Ceci est particulièrement utile, par exemple, sur une page d'archive de date ou de catégorie. Si quelqu'un navigue vers une page qui n'a pas de publication, il est agréable d'avoir un message qui l'indique, plutôt que de ne rien afficher du tout, car la boucle n'est jamais exécutée.

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