Combinaison de requêtes avec différents arguments par type de publication

11

Je crée une section sur un site où je fusionne deux types de messages différents en une seule boucle, puis les affiche au hasard. Le problème est que j'ai du mal à trouver un moyen de limiter la quantité de messages par type.

Voici ce que j'ai essayé:

  • Une requête avec plusieurs types de publication peut être réalisée avec un tableau:

    $args = array( 'post_type' => array( 'photos', 'quotes' ), ...

    ... mais ne peut se limiter à un certain nombre de publications par type.

  • Fusion de deux tableaux d'arguments de requête avant d'exécuter WP_Query dessus:

    $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;
    // Also tried array_merge( $photos, $quotes );

    Pas de chance là-dessus. Ce qui se passe, c'est que cette dernière variable $quotesécrase $photoset n'affiche que les guillemets.

  • Fusion de deux objets WP_Query ensemble par le transtypage:

    $photos_query = new WP_Query( $photos );
    $quotes_query = new WP_Query( $quotes );
    $result = (object)array_merge( (array)$photos_query, (array)$quotes_query );

... etc.

Je pourrais probablement utiliser une requête SQL directement dans la base de données, mais je dois pouvoir combiner ces deux types de messages séparés pour une boucle, disposés de manière aléatoire ET limités à une certaine quantité de messages par type.

Merci de votre aide!

Andy Merskin
la source

Réponses:

16

Une façon consiste à personnaliser la requête SQL exécutée à l'aide de posts_clausesou d'autres filtres de ce type. Pour les trouver, recherchez posts_clausesdans "wp-includes / query.php" et voyez la série de filtres juste avant cette ligne. Ensemble, ils sont capables de personnaliser n'importe quelle partie de la requête

Une autre chose que vous pouvez faire est de fusionner manuellement les messages interrogés dans les objets

$photos_query = new WP_Query( $photos );
$quotes_query = new WP_Query( $quotes );
$result = new WP_Query();

// start putting the contents in the new object
$result->posts = array_merge( $photos_query->posts, $quotes_query->posts );

// here you might wanna apply some sort of sorting on $result->posts

// we also need to set post count correctly so as to enable the looping
$result->post_count = count( $result->posts );
Mridul Aggarwal
la source
Votre deuxième solution (sans SQL) a fait l'affaire! Maintenant, j'ai un contrôle complet sur ce qui va dans cette requête finale avant d'entrer dans la boucle. Merci de votre aide!
Andy Merskin
1
La première est difficile mais plus efficace (dans la seconde il y a encore 2 requêtes de base de données). Je dirais que cela
dépend de vos
Serait extrêmement intéressé par un moyen d'accomplir la première solution! Les filtres nécessaires, etc. Cela appelle-t-il une UNIONsorte de code dans le sql pour chaque post_type?
Solomon Closson
@SolomonClosson ce filtre peut aider- codex.wordpress.org/Plugin_API/Filter_Reference/posts_clauses
Mridul Aggarwal
7

@mridual aggarwal votre réponse est très très bonne mais malheureusement, elle ne combine pas vraiment les 2, wp_queryelle ne montre que les messages des deux en ordre, je veux dire 5 messages du premier et 5 du second mais pas triés tout en un, donc j'ai ceci solution et il a exactement atteint l'objectif pour moi au moins

<?php
$term = get_term_by( 'slug', get_query_var( 'tag' ), "post_tag" );
$tagslug = $term->slug;
$post_types = get_post_types('','names');
?>
<?php
//first query
$blogposts = get_posts(array(
    'tag' => $tagslug, //first taxonomy
    'post_type' => $post_types,
    'post_status' => 'publish',
    ));
//second query
$authorposts = get_posts(array(
    'bookauthor' => $tagslug, //second taxonomy
    'post_type' => $post_types,
    'post_status' => 'publish',
    ));
$mergedposts = array_merge( $blogposts, $authorposts ); //combine queries

$postids = array();
foreach( $mergedposts as $item ) {
$postids[]=$item->ID; //create a new query only of the post ids
}
$uniqueposts = array_unique($postids); //remove duplicate post ids

$posts = get_posts(array(
        //new query of only the unique post ids on the merged queries from above
    'post__in' => $uniqueposts,  
    'post_type' => $post_types,
    'post_status' => 'publish',
    ));
foreach( $posts as $post ) :
setup_postdata($post);
?>
// posts layout
<?php endforeach; ?>
<?php wp_reset_postdata();?>
adnan
la source