Przeczytałem @ nacin's Nie znasz zapytania wczoraj i wysłano mi trochę pytającej króliczej nory. Przed wczoraj (niesłusznie) korzystałem query_posts()
ze wszystkich moich potrzeb związanych z zapytaniami. Teraz jestem trochę mądrzejszy w używaniu WP_Query()
, ale nadal mam kilka szarych obszarów.
Co myślę, że wiem na pewno:
Jeśli robię dodatkowe pętle w dowolnym miejscu na stronie - na pasku bocznym, w stopce, wszelkiego rodzaju „powiązanych postach” itp. - chcę z nich korzystać WP_Query()
. Mogę używać tego wielokrotnie na jednej stronie bez szkody. (dobrze?).
Czego nie wiem na pewno
- Kiedy używam @ nacin w
pre_get_posts
wersetachWP_Query()
? Czy mampre_get_posts
teraz używać do wszystkiego? - Kiedy chcę zmodyfikować pętlę na stronie szablonu - powiedzmy, że chcę zmodyfikować stronę archiwum systematyki - czy mogę usunąć
if have_posts : while have_posts : the_post
część i napisać własnąWP_Query()
? Czy mogę zmodyfikować dane wyjściowe za pomocąpre_get_posts
mojego pliku functions.php?
tl; dr
Zasady tl; dr, które chciałbym z tego wyciągnąć, to:
- Nigdy
query_posts
więcej nie używaj - Jeśli uruchamiasz wiele zapytań na jednej stronie, użyj
WP_Query()
- Podczas modyfikowania pętli wykonaj to __________________.
Dzięki za wszelką mądrość
Terry
ps: Widziałem i czytałem: kiedy powinieneś używać WP_Query vs query_posts () vs get_posts ()? Co dodaje kolejny wymiar get_posts
. Ale w ogóle się nie zajmuje pre_get_posts
.
Odpowiedzi:
Masz rację, mówiąc:
pre_get_posts
pre_get_posts
to filtr służący do zmiany dowolnego zapytania. Najczęściej służy do zmiany tylko „głównego zapytania”:(Sprawdziłbym również, czy
is_admin()
zwraca false - choć może to być zbędne). Główne zapytanie pojawia się w szablonach jako:Jeśli kiedykolwiek poczujesz potrzebę edycji tej pętli - użyj
pre_get_posts
. tj. Jeśli masz ochotę użyćquery_posts()
- użyjpre_get_posts
zamiast tego.WP_Query
Główne zapytanie jest ważną instancją pliku
WP_Query object
. WordPress używa go na przykład, aby zdecydować, którego szablonu użyć, a wszelkie argumenty przekazane do adresu URL (np. Pagination) są przekazywane do tej instancjiWP_Query
obiektu.W przypadku pętli wtórnych (np. Na paskach bocznych lub listach „pokrewnych postów”) będziesz chciał stworzyć własną oddzielną instancję
WP_Query
obiektu. Na przykładUwaga
wp_reset_postdata();
- dzieje się tak, ponieważ pętla wtórna zastąpi$post
zmienną globalną , która identyfikuje „bieżący post”. Zasadniczo resetuje to, że$post
jesteśmy na.get_posts ()
Jest to zasadniczo opakowanie dla oddzielnej instancji
WP_Query
obiektu. Zwraca tablicę obiektów postu. Metody zastosowane w powyższej pętli nie są już dostępne. To nie jest „Pętla”, po prostu tablica obiektu pocztowego.W odpowiedzi na twoje pytania
pre_get_posts
do zmiany głównego zapytania. Użyj osobnegoWP_Query
obiektu (metoda 2) dla pętli wtórnych na stronach szablonu.pre_get_posts
.źródło
get_posts()
jest to bardziej wydajne.get_posts()
do głównego zapytania - jest to dla zapytań wtórnych.Istnieją dwa różne konteksty dla pętli:
Problem
query_posts()
polega na tym, że jest to pętla wtórna, która próbuje być główną, i kończy się niepowodzeniem. Zapomnij o tym, że istnieje.Aby zmodyfikować główną pętlę
query_posts()
pre_get_posts
filtra z$query->is_main_query()
czekiemrequest
filtra (trochę za szorstki, więc wyżej jest lepiej)Aby uruchomić pętlę wtórną
Użyj
new WP_Query
lubget_posts()
które są prawie wymienne (ten drugi jest cienkim opakowaniem dla byłego).Posprzątać
Użyj,
wp_reset_query()
jeśli bezpośrednioquery_posts()
używałeś globalnej komunikacji$wp_query
- więc prawie nigdy nie będziesz musiał tego robić.Użyj
wp_reset_postdata()
jeśli używanythe_post()
lubsetup_postdata()
lub pomieszane z globalnym$post
i trzeba przywrócić stan początkowy z Related Post-rzeczy.źródło
wp_reset_postdata()
Istnieją uzasadnione scenariusze użycia
query_posts($query)
, na przykład:Chcesz wyświetlić listę postów lub niestandardowych postów na stronie (za pomocą szablonu strony)
Chcesz, aby paginacja tych postów działała
Dlaczego chcesz wyświetlać go na stronie zamiast szablonu archiwum?
Jest to bardziej intuicyjne dla administratora (Twojego klienta?) - oni mogą zobaczyć stronę na „Stronach”
Lepiej jest dodać go do menu (bez strony musieliby dodać adres URL bezpośrednio)
Jeśli chcesz wyświetlić dodatkową treść (tekst, miniaturę postu lub dowolną niestandardową meta treść) w szablonie, możesz łatwo pobrać ją ze strony (i to wszystko ma sens również dla klienta). Sprawdź, czy korzystasz z szablonu archiwum, musisz albo zakodować dodatkową zawartość, albo użyć na przykład opcji motywu / wtyczki (co czyni to mniej intuicyjnym dla klienta)
Oto uproszczony przykładowy kod (który byłby na szablonie strony - np. Page-page-of-posts.php):
Teraz, aby być całkowicie jasnym, moglibyśmy również uniknąć używania
query_posts()
tutaj i używaćWP_Query
zamiast tego - tak:Ale dlaczego mielibyśmy to robić, skoro mamy do dyspozycji tak ładną, małą funkcję?
źródło
Zmieniam zapytanie WordPress z functions.php:
źródło
Wystarczy przedstawić kilka poprawek do zaakceptowanej odpowiedzi, ponieważ WordPress ewoluował w czasie, a niektóre rzeczy są teraz inne (pięć lat później):
Właściwie to hak akcji. Nie filtr, i wpłynie na każde zapytanie.
W rzeczywistości nie jest to również prawdą. Funkcja
have_posts
iterujeglobal $wp_query
obiekt, który nie jest powiązany tylko z głównym zapytaniem.global $wp_query;
mogą być również zmieniane za pomocą dodatkowych zapytań.Właściwie w dzisiejszych czasach
WP_Query
jest klasa, więc mamy instancję klasy.Podsumowując: w tym czasie @StephenHarris najprawdopodobniej napisał wszystko, co było prawdą, ale z czasem rzeczy w WordPressie uległy zmianie.
źródło
get_posts
zwraca tablicę obiektów postu, a nieWP_Query
obiekt, więc to rzeczywiście jest poprawne. iWP_Query
zawsze była klasą, instancją klasy = obiekt.