Combinare query con argomenti diversi per tipo di post
Sto creando una sezione su un sito dove sto unendo due diversi tipi di post in un unico loop, mostrandoli in modo casuale. Il problema è che sto avendo difficoltà a trovare un modo per limitare il numero di post per tipo.
Ecco cosa ho provato:
Una query con più tipi di post può essere ottenuta con un array:
$args = array( 'post_type' => array( 'photos', 'quotes' ), ...
... ma non può essere limitata a un certo numero di post per tipo.
Unire due array di argomenti query prima di eseguire WP_Query:
$photos = array( 'post_type' => 'photos', 'posts_per_page' => 15, 'orderby' => 'rand' ); $quotes = array( 'post_type' => 'quotes', 'posts_per_page' => 5, 'orderby' => 'rand' ); $args = $photos + $quotes; // Ho provato anche array_merge( $photos, $quotes );
Nessun successo qui. Quello che succede è che la seconda variabile
$quotes
sovrascrive$photos
e mostra solo le citazioni.Unire due oggetti WP_Query insieme attraverso il type casting:
$photos_query = new WP_Query( $photos ); $quotes_query = new WP_Query( $quotes ); $result = (object)array_merge( (array)$photos_query, (array)$quotes_query );
... e così via.
Potrei probabilmente utilizzare una query SQL diretta al database, ma ho bisogno di poter combinare questi due tipi di post separati in un unico loop, disposti in modo casuale, E limitati a una certa quantità di post per tipo.
Grazie per il vostro aiuto!

Un modo è personalizzare la query SQL eseguita utilizzando i filtri posts_clauses
o altri simili. Per trovarli cerca posts_clauses
in "wp-includes/query.php" e vedi la serie di filtri appena prima di questa riga. Insieme, questi sono in grado di personalizzare qualsiasi parte della query
Un'altra cosa che puoi fare è unire manualmente i post interrogati negli oggetti
$photos_query = new WP_Query( $photos );
$quotes_query = new WP_Query( $quotes );
$result = new WP_Query();
// inizia a inserire i contenuti nel nuovo oggetto
$result->posts = array_merge( $photos_query->posts, $quotes_query->posts );
// qui potresti voler applicare qualche tipo di ordinamento su $result->posts
// dobbiamo anche impostare correttamente il conteggio dei post per abilitare il loop
$result->post_count = count( $result->posts );

La tua seconda soluzione (senza SQL) ha funzionato alla perfezione! Ora ho il controllo completo su ciò che viene inserito nella query finale prima di entrare nel loop. Grazie per l'aiuto!

La prima è più complessa ma più efficiente (nella seconda ci sono ancora 2 query al database). Direi che dipende dalle preferenze personali

Sarei estremamente interessato a un modo per realizzare la prima soluzione! I filtri necessari, ecc. Richiede una UNION
di qualche tipo nell'SQL per ogni post_type?

@SolomonClosson questo filtro può aiutare - https://codex.wordpress.org/Plugin_API/Filter_Reference/posts_clauses

@mridual aggarwal la tua risposta è molto molto buona ma purtroppo non combina realmente i 2 wp_query
, mostra solo i post di entrambi in ordine, intendo 5 post dal primo e 5 dal secondo ma non tutti ordinati insieme. Quindi ho questa soluzione che, almeno per me, raggiunge esattamente l'obiettivo
<?php
$term = get_term_by( 'slug', get_query_var( 'tag' ), "post_tag" );
$tagslug = $term->slug;
$post_types = get_post_types('','names');
?>
<?php
//prima query
$blogposts = get_posts(array(
'tag' => $tagslug, //prima tassonomia
'post_type' => $post_types,
'post_status' => 'publish',
));
//seconda query
$authorposts = get_posts(array(
'bookauthor' => $tagslug, //seconda tassonomia
'post_type' => $post_types,
'post_status' => 'publish',
));
$mergedposts = array_merge( $blogposts, $authorposts ); //combina le query
$postids = array();
foreach( $mergedposts as $item ) {
$postids[]=$item->ID; //crea una nuova query solo con gli ID dei post
}
$uniqueposts = array_unique($postids); //rimuove gli ID dei post duplicati
$posts = get_posts(array(
//nuova query solo con gli ID univoci dei post dalle query unite sopra
'post__in' => $uniqueposts,
'post_type' => $post_types,
'post_status' => 'publish',
));
foreach( $posts as $post ) :
setup_postdata($post);
?>
// layout dei post
<?php endforeach; ?>
<?php wp_reset_postdata();?>
