Query personalizzate di WordPress: utilizzo della classe WP_Query

Pubblicato: 2021-02-06

WordPress offre una vasta gamma di funzioni pronte all'uso che nella maggior parte dei casi possono recuperare le informazioni necessarie dal database. Ma quando si sviluppa un sito Web WordPress ci sono numerosi scenari in cui un filtro o un'azione non sono sufficienti per ottenere il risultato desiderato. In questi casi. WordPress offre una soluzione alternativa sotto forma della classe WP_Query .

Diamo un'occhiata a come può essere utilizzata la classe WP_Query !

Casi di query personalizzati

NOTA: questo articolo presuppone che tu abbia una certa conoscenza di PHP e MySQL/MariaDB e che tu abbia familiarità con WordPress.

Qualunque sia la pagina che visiti, WordPress esegue quella che viene chiamata una "query principale" per visualizzare il contenuto. Quindi, quando visiti una pagina come una vista per categoria, ad esempio, un oggetto WP_Query viene creato dietro le quinte e recupera tutti i dati necessari dal database per visualizzare la pagina.

Ciò che sostanzialmente fa WP_Query è offrirti la possibilità di recuperare il contenuto dal database del tuo sito Web senza dover utilizzare query SQL.

Per fare ciò, tutto ciò che dobbiamo fare è definire gli argomenti corrispondenti alle nostre esigenze e verrà creato un nuovo oggetto WP_Query e tradotto in una query SQL.

Un esempio che utilizza WP_Query

Se vogliamo visualizzare i post di una categoria specifica, all'interno di un altro modello di categoria, è necessario creare un nuovo oggetto query.

Ai fini di questo esempio abbiamo attivato il tema Twenty Twenty e creato 2 post in una categoria denominata "Categoria 1" e 2 post in una categoria denominata "Servizi".

Inoltre, abbiamo creato un modello di visualizzazione per categoria personalizzato per i post "Categoria 1". Lo slug di questa categoria è 'categoria-1' quindi il file nella cartella del tema dovrebbe essere category-CATEGORYSLUG.php che nel nostro caso è category-category-1.php .

Si prega di incollare quanto segue nel file 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(); ?>

Prima del ciclo utilizziamo il metodo have_posts per determinare se ci sono più post disponibili nel ciclo.

the_post() è necessario affinché il ciclo itera i post e dica a WordPress di passare al post successivo dell'array dei post.

A questo punto la nostra vista frontend della categoria ( https://mycompanyname.com/category/category-1/ ) sarà qualcosa del genere:

So che usando questo pezzo di codice abbiamo trascurato di includere molte informazioni sui post, ma per il bene di questo esempio, è meglio mantenerlo semplice e visualizzare solo i titoli dei post.

Per vedere le proprietà dell'oggetto query che WordPress ha creato per questa vista, possiamo semplicemente aggiungere questa riga nel nostro codice dopo l' endif; dichiarazione.

 var_dump ( $wp_query->query_vars );

Ora se aggiorni la tua pagina troverai queste informazioni nell'elenco dei post:

 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" }

Diciamo che vogliamo visualizzare l'elenco dei post che appartengono alla categoria "Servizi" sotto i post illustrati sopra. Poiché la pagina ha già creato un oggetto query per la categoria corrente, dovremo aggirare il problema manipolando gli argomenti della query principale esistenti.

Diamo un'occhiata ai modi in cui WordPress ci consente di raggiungere questo obiettivo.

La funzione query_posts

La funzione query_posts() è un modo per modificare la query principale utilizzata da WordPress per visualizzare i post. Lo fa mettendo da parte la query principale e sostituendola con una nuova query. Puoi vederlo di persona nel file wp-includes/query.php in cui viene introdotto.

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

Cercheremo di aggiungere un altro ciclo per visualizzare i post "Servizi" aggiungendo le seguenti righe sotto il endwhile; dell'attuale ciclo standard.

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

Ed ecco qua:

C'è tuttavia uno svantaggio in questo metodo. Se proviamo a stampare la categoria inclusa nell'oggetto della query noteremo che è alterata.

Prova a inserire var_dump ( $wp_query->query_vars["category_name"] ); dopo la query Servizi e aggiorna la pagina. Dovresti vedere questo risultato:

 string(8) "services"

Ciò è accaduto perché la query è stata modificata ma non è mai stata ripristinata. Questo approccio può causare molti problemi con i contenuti che seguono le nostre domande.

Per evitare questi conflitti e ripulire dopo una chiamata a query_posts , effettuare una chiamata a wp_reset_query() e la query principale originale verrà ripristinata. Quindi il tuo codice dovrebbe assomigliare a questo:

 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"] );

Dopo aver aggiornato la tua pagina, ora vedrai che la categoria della pagina iniziale è tornata nella query.

 string(10) "category-1"

Infine, dovremmo menzionare che query_posts dovrebbe essere evitato in quanto aggiunge un sovraccarico alla tua query poiché in realtà fa sì che la query principale venga nuovamente eseguita.

La funzione get_posts()

Lo stesso risultato può essere ottenuto con l'uso della funzione get_posts() per recuperare un array di post che corrispondono ai criteri indicati.

Sostituisci il ciclo Servizi mostrato di seguito...

 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"] );

…con questo:

 $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"] );

Come puoi vedere questa volta abbiamo dovuto lavorare con l'id della categoria invece del nome della categoria, secondo gli argomenti get_posts() definiti da WordPress.

Un'altra cosa importante da notare qui è che anche se non abbiamo reimpostato la query, l'output var_dump della categoria della query era ancora intatto e non modificato in "servizi". Questo perché get_posts() da solo non altera la query principale. Abbiamo appena utilizzato una nuova variabile ' $my_query ' per creare una nuova istanza dell'oggetto query senza sostituirlo.

La funzione get_posts() utilizza gli stessi parametri di query_posts() ed è consigliata per l'uso quando si desidera aggiungere loop statici personalizzati in qualsiasi punto del modello poiché è sicura e facile da usare.

Crea un nuovo oggetto WP_Query

$wp_query è un oggetto della classe WP_Query e recupera il contenuto del database necessario per la pagina corrente. L'override di questa classe è il nostro modo di personalizzare i risultati e visualizzare contenuti diversi.

Questo è il pezzo di codice che useremo:

 $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"] );

Abbiamo usato l'argomento 'nome_categoria' per definire lo slug della categoria in cui vogliamo che vengano visualizzati i suoi post.

Abbiamo salvato il nuovo oggetto new WP_Query( 'category_name=services' ); nella variabile $services_query .

Quindi abbiamo usato un ciclo while per visualizzare il contenuto e dopo questo abbiamo ripristinato il ciclo con wp_reset_postdata(); per ripristinare i dati originali della query principale.

Se vuoi sperimentare altri argomenti della classe WP_Query WordPress puoi trovare l'elenco completo nella sua pagina del Codice di WordPress.