Ich habe gestern bei @nacin's " Du kennst Query" gelesen und wurde ein bisschen in ein Kaninchenloch geschickt, in dem nachgefragt wurde. Vor gestern habe ich (zu Unrecht) query_posts()
alle meine Abfrageanforderungen erfüllt. Jetzt bin ich ein bisschen weiser im Umgang mit WP_Query()
, habe aber noch einige Grauzonen.
Was ich mit Sicherheit zu wissen glaube:
Wenn ich irgendwo auf einer Seite zusätzliche Schleifen mache - in der Seitenleiste, in einer Fußzeile, in "verwandten Beiträgen" usw. - möchte ich diese verwenden WP_Query()
. Ich kann das wiederholt auf einer einzelnen Seite ohne Schaden verwenden. (richtig?).
Was ich nicht sicher weiß
- Wann verwende ich @ nacin des
pre_get_posts
vs.WP_Query()
? Soll ichpre_get_posts
jetzt für alles verwenden? - Wenn ich die Schleife in einer Vorlagenseite ändern möchte - sagen wir, ich möchte eine Taxonomie-Archivseite ändern - entferne ich den
if have_posts : while have_posts : the_post
Teil und schreibe meinen eigenenWP_Query()
? Oder ändere ich die Ausgabepre_get_posts
in meiner functions.php Datei?
tl; dr
Die Regeln, die ich hieraus ziehen möchte, sind:
- Nie
query_posts
mehr benutzen - Wenn Sie mehrere Abfragen auf einer Seite ausführen, verwenden Sie
WP_Query()
- Wenn Sie eine Schleife ändern, gehen Sie wie folgt vor: __________________.
Danke für jede Weisheit
Terry
PS: Ich habe gesehen und gelesen: Wann sollten Sie WP_Query vs query_posts () vs get_posts () verwenden? Was eine weitere Dimension hinzufügt - get_posts
. Beschäftigt sich aber überhaupt nicht pre_get_posts
.
quelle
Antworten:
Sie haben Recht zu sagen:
pre_get_posts
pre_get_posts
ist ein Filter zum Ändern von Abfragen. Es wird am häufigsten verwendet, um nur die 'Hauptabfrage' zu ändern:(Ich würde auch prüfen, ob die
is_admin()
Rückgabe falsch ist - obwohl dies redundant sein kann.) Die Hauptabfrage erscheint in Ihren Vorlagen als:Wenn Sie jemals das Bedürfnis haben, diese Schleife zu bearbeiten, verwenden Sie
pre_get_posts
. Wenn Sie versucht sind zu verwenden,query_posts()
verwenden Siepre_get_posts
stattdessen.WP_Query
Die Hauptabfrage ist eine wichtige Instanz von a
WP_Query object
. WordPress verwendet es, um zu entscheiden, welche Vorlage verwendet werden soll, und alle Argumente, die an die URL übergeben werden (z. B. Paginierung), werden in diese Instanz desWP_Query
Objekts geleitet.Für sekundäre Schleifen (z. B. in Seitenleisten oder Listen mit verwandten Posts) möchten Sie eine eigene Instanz des
WP_Query
Objekts erstellen . Z.BHinweis
wp_reset_postdata();
- Dies liegt daran, dass die sekundäre Schleife die globale$post
Variable überschreibt , die den 'aktuellen Beitrag' identifiziert. Dies setzt im Wesentlichen das zurück, worauf$post
wir uns befinden.get_posts ()
Dies ist im Wesentlichen ein Wrapper für eine separate Instanz eines
WP_Query
Objekts. Dies gibt ein Array von Post-Objekten zurück. Die in der obigen Schleife verwendeten Methoden stehen Ihnen nicht mehr zur Verfügung. Dies ist keine 'Schleife', sondern nur ein Array von Post-Objekten.Als Antwort auf Ihre Fragen
pre_get_posts
, um Ihre Hauptabfrage zu ändern. Verwenden Sie ein separatesWP_Query
Objekt (Methode 2) für sekundäre Schleifen in den Vorlagenseiten.pre_get_posts
.quelle
get_posts()
ist dies effizienter.get_posts()
für die Hauptabfrage verwenden - es ist für sekundäre Abfragen.Es gibt zwei verschiedene Kontexte für Schleifen:
Das Problem
query_posts()
ist, dass es eine sekundäre Schleife ist, die versucht, die Hauptschleife zu sein und kläglich versagt. Also vergiss, dass es existiert.Hauptschleife ändern
query_posts()
pre_get_posts
Filter mit$query->is_main_query()
Scheckrequest
Filter verwenden (etwas zu rau, daher besser oben)Sekundäre Schleife ausführen
Verwenden Sie
new WP_Query
oderget_posts()
die ziemlich austauschbar sind (letzteres ist dünne Hülle für erstere).Aufräumen
Verwenden
wp_reset_query()
Sie diesequery_posts()
Option, wenn Sie Global$wp_query
direkt verwendet haben oder damit in Konflikt geraten sind - dies wird so gut wie nie erforderlich sein.Verwenden
wp_reset_postdata()
Sie diese Option, wenn Sie " global" verwendet habenthe_post()
oder damitsetup_postdata()
herumgespielt haben$post
und den Anfangszustand von nachträglichen Dingen wiederherstellen müssen.quelle
wp_reset_postdata()
Es gibt legitime Szenarien für die Verwendung
query_posts($query)
, zum Beispiel:Sie möchten eine Liste von Posts oder benutzerdefinierten Posts auf einer Seite anzeigen (mithilfe einer Seitenvorlage).
Sie möchten, dass die Paginierung dieser Posts funktioniert
Warum sollten Sie es nun auf einer Seite anzeigen, anstatt eine Archivvorlage zu verwenden?
Für einen Administrator (Ihren Kunden?) Ist es intuitiver - er kann die Seite unter "Seiten" sehen.
Es ist besser, es zu Menüs hinzuzufügen (ohne die Seite müssten sie die URL direkt hinzufügen)
Wenn Sie zusätzlichen Inhalt (Text, Miniaturansicht des Beitrags oder benutzerdefinierten Metainhalt) in der Vorlage anzeigen möchten, können Sie ihn problemlos von der Seite abrufen (und dies ist auch für den Kunden sinnvoller). Wenn Sie eine Archivvorlage verwendet haben, müssen Sie entweder den zusätzlichen Inhalt fest codieren oder beispielsweise Themen- / Plug-in-Optionen verwenden (dies macht es für den Kunden weniger intuitiv).
Hier ist ein vereinfachter Beispielcode (der sich auf Ihrer Seitenvorlage befinden würde - zB page-page-of-posts.php):
Nun, um ganz klar zu sein, könnten wir auch hier vermeiden
query_posts()
undWP_Query
stattdessen Folgendes verwenden:Aber warum sollten wir das tun, wenn wir so eine nette kleine Funktion zur Verfügung haben?
quelle
Ich ändere die WordPress-Abfrage von functions.php:
quelle
Um nur einige Verbesserungen an der akzeptierten Antwort zu skizzieren, seit sich WordPress im Laufe der Zeit weiterentwickelt hat und einige Dinge jetzt (fünf Jahre später) anders sind:
Eigentlich ist das ein Aktionshaken. Kein Filter, und es wirkt sich auf jede Abfrage aus.
Eigentlich stimmt das auch nicht. Die Funktion
have_posts
iteriert dasglobal $wp_query
Objekt, das sich nicht nur auf die Hauptabfrage bezieht .global $wp_query;
kann auch mit den sekundären Abfragen geändert werden.Tatsächlich ist heutzutage
WP_Query
eine Klasse, also haben wir eine Instanz einer Klasse.Fazit: Zu der Zeit, als @StephenHarris schrieb, war dies höchstwahrscheinlich alles wahr, aber im Laufe der Zeit wurden die Dinge in WordPress geändert.
quelle
get_posts
Gibt ein Array von Post-Objekten zurück, keinWP_Query
Objekt, das ist also immer noch korrekt. und warWP_Query
schon immer eine Klasse, eine Instanz eines class = object.