WP_Query în WordPress

Interogări și bucla WordPress 1.5

Clasa care interoghează articole, pagini și tipuri personalizate după criterii: tip, categorie, câmpuri, ordine, paginare.

Sintaxă
$query = new WP_Query( array|string $query = '' );

Ce face WP_Query

WP_Query este clasa pe care WordPress o folosește intern pentru interogarea principală a fiecărei pagini. O poți folosi și tu, în temă sau în plugin, pentru o listă separată: ultimele 3 articole dintr-o categorie, produsele sub 50 de lei, evenimentele dintr-un oraș.

Primește un tablou de argumente și face interogarea imediat, în constructor. Rezultatul îl parcurgi cu o buclă proprie: $query->have_posts() și $query->the_post(). După buclă chemi wp_reset_postdata(), ca variabila globală $post să revină la articolul paginii curente.

Obiectul are proprietăți utile: posts (tabloul cu articole), post_count (câte sunt afișate acum), found_posts (câte se potrivesc în total) și max_num_pages (numărul de pagini). Ca să modifici interogarea principală (de exemplu numărul de articole din arhivă), nu crea un WP_Query nou: folosește hook-ul pre_get_posts.

Parametri

Parametru Descriere
post_type Tipul de conținut: 'post' (implicit), 'page', un tip personalizat sau un tablou de tipuri.
posts_per_page Câte articole pe pagină; -1 le aduce pe toate (atunci offset este ignorat).
paged Numărul paginii pentru paginare (de obicei get_query_var( 'paged' )). Pe o pagină statică de start se folosește page.
category_name Slug-ul categoriei (de exemplu 'evenimente').
orderby / order Criteriul de sortare (implicit 'date') și sensul: 'DESC' (implicit) sau 'ASC'. Pentru numere salvate în câmpuri: 'meta_value_num' împreună cu meta_key.
meta_query Filtrare după câmpuri personalizate: tablouri cu key, value, compare, type (din WordPress 3.1).
tax_query Filtrare după taxonomii: taxonomy, field, terms (din WordPress 3.1).
s Cuvânt de căutat în titlu și conținut.
post_status Starea articolelor; implicit 'publish'.
no_found_rows true sare peste numărarea totalului (mai rapid când nu ai nevoie de paginare). Implicit false.
fields 'ids' întoarce doar ID-uri, 'id=>parent' ID-uri și părinți; implicit obiecte complete.

Ce returnează

Un obiect WP_Query. Articolele găsite sunt în $query->posts; totalul în $query->found_posts, numărul de pagini în $query->max_num_pages.

Exemple

Exemplul 1: Ultimele 3 articole dintr-o categorie

O listă separată în bara laterală, cu bucla obiectului și wp_reset_postdata() la final.

<?php
$evenimente = new WP_Query( array(
    'category_name'  => 'evenimente',
    'posts_per_page' => 3,
    'no_found_rows'  => true,
) );

if ( $evenimente->have_posts() ) : ?>
    <ul class="evenimente">
        <?php while ( $evenimente->have_posts() ) : $evenimente->the_post(); ?>
            <li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
        <?php endwhile; ?>
    </ul>
<?php endif;
wp_reset_postdata();

Ce afișează pagina

<ul class="evenimente">
    <li><a href="https://exemplu.ro/concert-in-parcul-copou/">Concert în Parcul Copou</a></li>
    <li><a href="https://exemplu.ro/targ-de-carte-cluj/">Târg de carte la Cluj</a></li>
    <li><a href="https://exemplu.ro/degustare-la-cafenea-iasi/">Degustare la Cafenea Iași</a></li>
</ul>

Exemplul 2: Produse sub 50 de lei, sortate după preț

meta_query cu type NUMERIC compară numere, nu texte; meta_value_num sortează numeric după cheia din meta_key.

<?php
$ieftine = new WP_Query( array(
    'post_type'      => 'produs',
    'posts_per_page' => 10,
    'meta_key'       => 'pret',
    'orderby'        => 'meta_value_num',
    'order'          => 'ASC',
    'meta_query'     => array(
        array(
            'key'     => 'pret',
            'value'   => 50,
            'compare' => '<=',
            'type'    => 'NUMERIC',
        ),
    ),
) );

foreach ( $ieftine->posts as $produs ) {
    printf(
        "<p>%s: %s lei</p>\n",
        esc_html( get_the_title( $produs ) ),
        esc_html( get_post_meta( $produs->ID, 'pret', true ) )
    );
}

Ce afișează pagina

<p>Cană ceramică: 25 lei</p>
<p>Cafea boabe 250 g: 38 lei</p>
<p>Ceai de tei: 45 lei</p>

Exemplul 3: Totalul și numărul de pagini, din terminal

Cu wp eval vezi rapid ce găsește o interogare: found_posts numără toate potrivirile, nu doar cele 5 de pe pagină.

wp eval '$q = new WP_Query( array( "post_type" => "post", "posts_per_page" => 5 ) ); echo $q->found_posts . " articole, " . $q->max_num_pages . " pagini";'

Ieșire în terminal

37 articole, 8 pagini

Greșeli frecvente

  • Uiți wp_reset_postdata() după o buclă proprie: funcțiile de după (the_title(), comentariile, câmpurile) arată datele ultimului articol din lista ta, nu ale paginii.
  • Creezi un WP_Query nou (sau folosești query_posts()) ca să schimbi lista principală dintr-o arhivă: paginarea nu se mai potrivește. Pentru interogarea principală folosește pre_get_posts.
  • Sortezi un preț cu 'orderby' => 'meta_value': valorile se compară ca text (100 înainte de 25). Pentru numere folosește meta_value_num.
  • Pui 'posts_per_page' => -1 pe un site cu mii de articole: interogarea aduce tot și încarcă serverul. Limitează și paginează.

Comenzi înrudite

  • get_posts: Întoarce un tablou de articole după aceleași argumente ca WP_Query, fără să atingă bucla principală.
  • have_posts / the_post: Bucla WordPress (The Loop): have_posts() verifică dacă mai sunt articole, the_post() îl pregătește pe următorul.
  • pre_get_posts: Acțiunea care îți permite să schimbi parametrii unei interogări WP_Query înainte să ruleze, fără query_posts() în șablon.
  • get_post_meta / update_post_meta: Citește, salvează, adaugă și șterge câmpuri personalizate (post meta) ale unui articol: preț, oraș, cod produs.
  • register_post_type: Înregistrează un tip de conținut personalizat (produse, evenimente, rețete), cu meniu propriu în administrare.