J'ai lu @ nacin Tu ne connais pas Query hier et j'ai été envoyé à un trou de lapin interrogateur. Avant hier, j'utilisais (à tort) query_posts()
pour tous mes besoins d'interrogation. Maintenant, je suis un peu plus sage sur l'utilisation WP_Query()
, mais j'ai encore des zones grises.
Ce que je pense savoir à coup sûr:
Si je fais des boucles supplémentaires n'importe où sur une page - dans la barre latérale, dans un pied de page, dans n'importe quel type de "messages liés", etc., je veux utiliser WP_Query()
. Je peux l'utiliser à plusieurs reprises sur une seule page sans aucun dommage. (droite?).
Ce que je ne sais pas avec certitude
- Quand est-ce que j'utilise @ nacin
pre_get_posts
vsWP_Query()
? Devrais-je utiliserpre_get_posts
pour tout maintenant? - Lorsque je souhaite modifier la boucle dans une page de modèle (disons que je souhaite modifier une page d'archive de taxonomie), dois-je supprimer la
if have_posts : while have_posts : the_post
partie et écrire la mienneWP_Query()
? Ou dois-je modifier la sortie en utilisantpre_get_posts
dans mon fichier functions.php?
tl; dr
Les règles que je voudrais en tirer sont les suivantes:
- Ne jamais utiliser
query_posts
plus - Lorsque vous exécutez plusieurs requêtes sur une même page, utilisez
WP_Query()
- Lorsque vous modifiez une boucle, faites ceci __________________.
Merci pour toute sagesse
Terry
ps: j'ai vu et lu: quand utiliser WP_Query vs query_posts () vs get_posts ()? Ce qui ajoute une autre dimension - get_posts
. Mais ne traite pas pre_get_posts
du tout.
la source
Réponses:
Vous avez raison de dire:
pre_get_posts
pre_get_posts
est un filtre, pour modifier toute requête. Il est le plus souvent utilisé pour modifier uniquement la "requête principale":(Je voudrais également vérifier que
is_admin()
renvoie faux - bien que cela puisse être redondant.). La requête principale apparaît dans vos modèles en tant que:Si vous ressentez le besoin de modifier cette boucle, utilisez-la
pre_get_posts
. Par exemple, si vous êtes tenté d’utiliserquery_posts()
, utilisezpre_get_posts
plutôt.WP_Query
La requête principale est une instance importante de a
WP_Query object
. WordPress l'utilise pour décider quel modèle utiliser, par exemple, et tous les arguments passés dans l'URL (par exemple, la pagination) sont tous canalisés dans cette instance de l'WP_Query
objet.Pour les boucles secondaires (par exemple, dans les barres latérales ou les listes de «publications connexes»), vous voudrez créer votre propre instance distincte de l'
WP_Query
objet. Par exempleAvis
wp_reset_postdata();
- ceci est dû au fait que la boucle secondaire remplacera la$post
variable globale qui identifie la «publication actuelle». Cela remet essentiellement cela à la$post
nous sommes sur.get_posts ()
Il s'agit essentiellement d'un wrapper pour une instance distincte d'un
WP_Query
objet. Cela retourne un tableau d'objets post. Les méthodes utilisées dans la boucle ci-dessus ne vous sont plus disponibles. Ce n'est pas une "boucle", simplement un tableau d'objets post.En réponse à vos questions
pre_get_posts
pour modifier votre requête principale. Utilisez unWP_Query
objet séparé (méthode 2) pour les boucles secondaires dans les pages de modèle.pre_get_posts
.la source
get_posts()
c’est plus efficace.get_posts()
pour la requête principale - c'est pour les requêtes secondaires.Il existe deux contextes différents pour les boucles:
Le problème,
query_posts()
c’est que c’est une boucle secondaire qui essaie d’être principale et qui échoue lamentablement. Donc oubliez ça existe.Pour modifier la boucle principale
query_posts()
pre_get_posts
filtre avec$query->is_main_query()
contrôlerequest
filtre (un peu trop rugueux, donc c'est mieux, c'est mieux)Pour exécuter la boucle secondaire
Utilisez
new WP_Query
ouget_posts()
qui sont à peu près interchangeables (ce dernier est un emballage fin pour ancien).Nettoyer
Utilisez-le
wp_reset_query()
si vous avez utiliséquery_posts()
ou joué$wp_query
directement avec Global - vous n'aurez donc presque jamais besoin de le faire.Utilisez-le
wp_reset_postdata()
si vous avez utiliséthe_post()
ousetup_postdata()
joué avec Global$post
et que vous devez restaurer l'état initial des éléments post-liés.la source
wp_reset_postdata()
Il existe des scénarios légitimes d'utilisation
query_posts($query)
, par exemple:Vous souhaitez afficher une liste de publications ou des publications de type publication personnalisée sur une page (à l'aide d'un modèle de page)
Vous voulez faire de la pagination de ces messages
Maintenant, pourquoi voudriez-vous l'afficher sur une page au lieu d'utiliser un modèle d'archive?
C'est plus intuitif pour un administrateur (votre client?) - il peut voir la page dans les 'Pages'
C'est mieux pour l'ajouter aux menus (sans la page, il faudrait ajouter l'URL directement)
Si vous souhaitez afficher du contenu supplémentaire (texte, miniature de publication ou tout méta contenu personnalisé) sur le modèle, vous pouvez facilement l'obtenir à partir de la page (et tout cela est plus logique pour le client également). Voyez si vous avez utilisé un modèle d’archive, vous devez coder en dur le contenu supplémentaire ou utiliser, par exemple, des options de thème / plugin (ce qui le rend moins intuitif pour le client).
Voici un exemple de code simplifié (qui se trouverait sur votre modèle de page - par exemple page-page-of-posts.php):
Maintenant, pour être parfaitement clair, nous pourrions éviter d’utiliser
query_posts()
ici aussi et utiliser à laWP_Query
place - comme ceci:Mais pourquoi ferions-nous cela alors que nous avons une si jolie petite fonction à sa disposition?
la source
Je modifie la requête WordPress à partir de functions.php:
la source
Juste pour souligner quelques améliorations à la réponse acceptée depuis que WordPress a évolué au fil du temps et certaines choses sont différentes maintenant (cinq ans plus tard):
Est en fait un crochet d’action. Ce n'est pas un filtre et cela affectera toute requête.
En fait, ce n'est pas vrai non plus. La fonction
have_posts
itère l'global $wp_query
objet qui n'est pas lié uniquement à la requête principale.global $wp_query;
peut être modifié avec les requêtes secondaires aussi.En fait, de nos jours
WP_Query
est une classe, nous avons donc une instance de classe.Pour conclure: à l'époque où @StephenHarris a très probablement écrit, tout cela était vrai, mais au fil du temps, les choses ont changé dans WordPress.
la source
get_posts
retourne un tableau d'objets post, pas unWP_Query
objet, donc c'est toujours correct. etWP_Query
a toujours été une classe, une instance d'un objet class =.