Niestandardowe zapytania WordPress – przy użyciu klasy WP_Query

Opublikowany: 2021-02-06

WordPress oferuje szeroką gamę gotowych do użycia funkcji, które w większości przypadków potrafią pobrać potrzebne informacje z bazy danych. Jednak podczas tworzenia witryny WordPress istnieje wiele scenariuszy, w których filtr lub działanie nie wystarczają do osiągnięcia pożądanego rezultatu. W tych przypadkach. WordPress oferuje obejście w postaci klasy WP_Query .

Przyjrzyjmy się, jak można użyć klasy WP_Query !

Przypadki zapytań niestandardowych

UWAGA: W tym artykule założono, że masz pewną wiedzę na temat PHP i MySQL/MariaDB, a ponadto znasz WordPressa.

Niezależnie od odwiedzanej strony WordPress uruchamia tak zwane „główne zapytanie”, aby wyświetlić zawartość. Kiedy więc odwiedzasz stronę, taką jak na przykład widok kategorii, obiekt WP_Query jest tworzony w tle i pobiera wszystkie niezbędne dane z bazy danych, aby wyświetlić stronę.

To, co w zasadzie robi WP_Query , to możliwość pobierania treści z bazy danych Twojej witryny bez konieczności używania zapytań SQL.

W tym celu wystarczy zdefiniować argumenty odpowiadające naszym potrzebom, a nowy obiekt WP_Query zostanie utworzony i przetłumaczony na zapytanie SQL.

Przykład z użyciem WP_Query

Jeśli chcemy wyświetlać posty z określonej kategorii, w ramach innego szablonu kategorii, konieczne jest utworzenie nowego obiektu zapytania.

Na potrzeby tego przykładu aktywowaliśmy motyw Twenty Twenty i utworzyliśmy 2 posty w kategorii o nazwie „Kategoria 1” i 2 posty w kategorii o nazwie „Usługi”.

Ponadto stworzyliśmy niestandardowy szablon widoku kategorii dla postów „Kategoria 1”. Ślimak tej kategorii to 'category-1', dlatego plik w folderze motywu powinien mieć postać category-CATEGORYSLUG.php , czyli w naszym przypadku category-category-1.php .

Proszę wkleić następujące elementy w pliku category-category-1.php .

 <?php /*** Custom Category 1 Template */ get_header(); ?> <main role="main"> <section class="site-content"> <div role="main"> <?php if ( have_posts() ) : ?> <header class="archive-header"> <h3 class="archive-title">Category: <?php single_cat_title( '', true ); ?></h3> </header> <?php while ( have_posts() ) : the_post(); the_title( '<h4 class="example"></h4>' ); endwhile; endif; ?> </div> </section> </main> <?php get_sidebar(); ?> <?php get_footer(); ?>

Przed pętlą używamy metody have_posts , aby określić, czy w pętli dostępnych jest więcej postów.

Funkcja the_post() jest niezbędna, aby pętla iterowała posty i nakazywała WordPressowi przejście do następnego posta w tablicy posts.

W tym momencie nasz frontendowy widok kategorii ( https://nazwafirmy.com/category/category-1/ ) będzie wyglądał mniej więcej tak:

Wiem, że korzystając z tego fragmentu kodu, zapomnieliśmy o podaniu wielu informacji o postach, ale ze względu na ten przykład lepiej jest zachować prostotę i wyświetlać tylko tytuły postów.

Aby zobaczyć właściwości obiektu zapytania, które WordPress stworzył dla tego widoku, możemy po prostu dodać ten wiersz w naszym kodzie po endif; oświadczenie.

 var_dump ( $wp_query->query_vars );

Teraz, jeśli odświeżysz swoją stronę, pod listą postów pojawi się ta informacja:

 array(63) { ["category_name"]=> string(10) "category-1" ["error"]=> string(0) "" ["m"]=> string(0) "" ["p"]=> int(0) ["post_parent"]=> string(0) "" ["subpost"]=> string(0) "" ["subpost_id"]=> string(0) "" ["attachment"]=> string(0) "" ["attachment_id"]=> int(0) ["name"]=> string(0) "" ["pagename"]=> string(0) "" ["page_id"]=> int(0) ["second"]=> string(0) "" ["minute"]=> string(0) "" ["hour"]=> string(0) "" ["day"]=> int(0) ["monthnum"]=> int(0) ["year"]=> int(0) ["w"]=> int(0) ["tag"]=> string(0) "" ["cat"]=> int(16) ["tag_id"]=> string(0) "" ["author"]=> string(0) "" ["author_name"]=> string(0) "" ["feed"]=> string(0) "" ["tb"]=> string(0) "" ["paged"]=> int(0) ["meta_key"]=> string(0) "" ["meta_value"]=> string(0) "" ["preview"]=> string(0) "" ["s"]=> string(0) "" ["sentence"]=> string(0) "" ["title"]=> string(0) "" ["fields"]=> string(0) "" ["menu_order"]=> string(0) "" ["embed"]=> string(0) "" ["category__in"]=> array(0) { } ["category__not_in"]=> array(0) { } ["category__and"]=> array(0) { } ["post__in"]=> array(0) { } ["post__not_in"]=> array(0) { } ["post_name__in"]=> array(0) { } ["tag__in"]=> array(0) { } ["tag__not_in"]=> array(0) { } ["tag__and"]=> array(0) { } ["tag_slug__in"]=> array(0) { } ["tag_slug__and"]=> array(0) { } ["post_parent__in"]=> array(0) { } ["post_parent__not_in"]=> array(0) { } ["author__in"]=> array(0) { } ["author__not_in"]=> array(0) { } ["ignore_sticky_posts"]=> bool(false) ["suppress_filters"]=> bool(false) ["cache_results"]=> bool(true) ["update_post_term_cache"]=> bool(true) ["lazy_load_term_meta"]=> bool(true) ["update_post_meta_cache"]=> bool(true) ["post_type"]=> string(0) "" ["posts_per_page"]=> int(10) ["nopaging"]=> bool(false) ["comments_per_page"]=> string(2) "50" ["no_found_rows"]=> bool(false) ["order"]=> string(4) "DESC" }

Załóżmy, że chcemy wyświetlić listę postów należących do kategorii „Usługi” pod postami przedstawionymi powyżej. Ponieważ strona utworzyła już obiekt zapytania dla bieżącej kategorii, będziemy musieli obejść ten problem, manipulując istniejącymi głównymi argumentami zapytania.

Przyjrzyjmy się, w jaki sposób WordPress pozwala nam to osiągnąć.

Funkcja query_posts

Funkcja query_posts() umożliwia zmianę głównego zapytania używanego przez WordPress do wyświetlania postów. Robi to, odkładając główne zapytanie na bok i zastępując je nowym zapytaniem. Możesz to zobaczyć na własne oczy w pliku wp-includes/query.php , w którym zostało to wprowadzone.

 function &query_posts($query) { unset($GLOBALS['wp_query']); $GLOBALS['wp_query'] =& new WP_Query(); return $GLOBALS['wp_query']->query($query); }

Spróbujemy dodać kolejną pętlę, aby wyświetlić posty „Usługi”, dodając następujące wiersze pod endwhile; bieżącej standardowej pętli.

 query_posts( array ( 'category_name' => 'services' ) ); while ( have_posts() ) : the_post(); the_title( '<h4 class="example"></h4>' ); endwhile;

I proszę bardzo:

Istnieje jednak wada tej metody. Jeśli spróbujemy wydrukować kategorię zawartą w obiekcie zapytania, zauważymy, że uległa ona zmianie.

Spróbuj wstawić var_dump ( $wp_query->query_vars["category_name"] ); po zapytaniu o Usługi i odświeżyć stronę. Powinieneś zobaczyć ten wynik:

 string(8) "services"

Stało się tak, ponieważ zapytanie zostało zmienione, ale nigdy nie zostało cofnięte. Takie podejście może powodować wiele problemów z treściami, które pojawiają się w naszych zapytaniach.

Aby uniknąć tych konfliktów i posprzątać po wywołaniu query_posts , wykonaj wywołanie wp_reset_query() , a pierwotne zapytanie główne zostanie przywrócone. Więc twój kod powinien wyglądać tak:

 query_posts( array ( 'category_name' => 'services' ) ); while ( have_posts() ) : the_post(); the_title( '<h4 class="example"></h4>' ); endwhile; wp_reset_query(); var_dump ( $wp_query->query_vars["category_name"] );

Po odświeżeniu strony zobaczysz, że w zapytaniu powróciła początkowa kategoria strony.

 string(10) "category-1"

Na koniec powinniśmy wspomnieć, że należy unikać query_posts , ponieważ zwiększa to obciążenie zapytania, ponieważ w rzeczywistości powoduje ponowne uruchomienie głównego zapytania.

Funkcja get_posts()

Ten sam wynik można osiągnąć za pomocą funkcji get_posts() , która pobiera tablicę wpisów spełniających podane kryteria.

Zastąp pętlę usług pokazaną poniżej…

 query_posts( array ( 'category_name' => 'services' ) ); while ( have_posts() ) : the_post(); the_title( '<h4 class="example"></h4>' ); endwhile; wp_reset_query(); var_dump ( $wp_query->query_vars["category_name"] );

…z tym:

 $my_query = get_posts( array ( 'category' => 17 ) ); foreach($my_query as $post) : setup_postdata($post); the_title( '<h4 class="example"></h4>' ); endforeach; var_dump ( $wp_query->query_vars["category_name"] );

Jak widać, tym razem musieliśmy pracować z identyfikatorem kategorii zamiast nazwy kategorii, zgodnie z argumentami get_posts() zdefiniowanymi przez WordPress.

Inną ważną rzeczą, na którą należy zwrócić uwagę, jest to, że chociaż nie zresetowaliśmy zapytania, dane wyjściowe var_dump kategorii zapytania pozostały nienaruszone i nie zostały zmienione na „usługi”. Dzieje się tak, ponieważ get_posts() sama w sobie nie zmienia głównego zapytania. Właśnie użyliśmy nowej zmiennej ' $my_query ', aby utworzyć nową instancję obiektu zapytania bez jego zastępowania.

Funkcja get_posts() używa tych samych parametrów, co query_posts() i jest zalecana do użycia, gdy chcesz dodać statyczne niestandardowe pętle w dowolnym miejscu szablonu, ponieważ jest bezpieczna i łatwa w użyciu.

Utwórz nowy obiekt WP_Query

$wp_query jest obiektem klasy WP_Query i pobiera niezbędną zawartość bazy danych dla bieżącej strony. Zastąpienie tej klasy to nasz sposób na dostosowanie wyników i wyświetlanie różnych treści.

Oto fragment kodu, którego użyjemy:

 $services_query = new WP_Query( 'category_name=services' ); if ( $services_query->have_posts() ) { while ( $services_query->have_posts() ) : $services_query->the_post(); the_title( '<h4 class="example"></h4>' ); endwhile; } wp_reset_postdata(); var_dump ( $wp_query->query_vars["category_name"] );

Użyliśmy argumentu 'category_name', aby zdefiniować informację dotyczącą kategorii, w której mają być wyświetlane jej posty.

Zapisaliśmy nowy obiekt new WP_Query( 'category_name=services' ); w zmiennej $services_query .

Następnie użyliśmy pętli while do wyświetlenia zawartości, a następnie zresetowaliśmy pętlę za pomocą wp_reset_postdata(); w celu przywrócenia pierwotnych danych głównego zapytania.

Jeśli chcesz poeksperymentować z innymi argumentami klasy WordPress WP_Query, możesz znaleźć pełną listę na stronie WordPress Codex.