Combinando consultas com diferentes argumentos por tipo de postagem

11

Estou construindo uma seção em um site onde estou mesclando dois tipos diferentes de postagem em um loop e exibindo-os aleatoriamente. O problema é que estou tendo dificuldades para encontrar uma maneira de limitar a quantidade de postagens por tipo.

Aqui está o que eu tentei:

  • Uma consulta com vários tipos de postagem pode ser alcançada com uma matriz:

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

    ... mas não pode se limitar a um determinado número de postagens por tipo.

  • Mesclando duas matrizes de argumentos de consulta antes de executar o 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;
    // Also tried array_merge( $photos, $quotes );

    Sem sorte nisso. O que acontece é que a última variável $quotessubstitui $photose mostra apenas as aspas.

  • Mesclando dois objetos WP_Query por meio da conversão de tipo:

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

... e assim por diante.

Provavelmente eu poderia usar uma consulta SQL diretamente no banco de dados, mas preciso combinar esses dois tipos de postagem separados para um loop, organizados aleatoriamente, E limitados a uma certa quantidade de postagens por tipo.

Obrigado pela ajuda!

Andy Merskin
fonte

Respostas:

16

Uma maneira é personalizar a consulta SQL executada usando posts_clauses ou outros filtros desse tipo. Para encontrá-los, procure posts_clausesem "wp-includes / query.php" e veja a série de filtros logo antes desta linha. Juntos, eles são capazes de personalizar qualquer parte da consulta

Outra coisa que você pode fazer é mesclar manualmente as postagens consultadas nos objetos

$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
fonte
Sua segunda solução (sem o SQL) fez o truque! Agora eu tenho controle total sobre o que está entrando na consulta final antes de entrar no loop. Obrigado pela ajuda!
Andy Merskin 5/11
1
O primeiro é difícil, mas mais eficiente (no segundo ainda existem 2 consultas ao banco de dados). Eu diria que se resume a preferência pessoal
Mridul Aggarwal
Ficaria extremamente interessado em conseguir a primeira solução! Os filtros necessários, etc. Isso exige UNIONalgum tipo de sql para cada post_type?
Solomon Closson
@SolomonClosson esse filtro pode ajudar- codex.wordpress.org/Plugin_API/Filter_Reference/posts_clauses
Mridul Aggarwal
7

@mridual aggarwal sua resposta é muito muito boa, mas infelizmente não está realmente combinando os 2 wp_query, apenas mostra os posts de ambos em organizar, quero dizer 5 posts do primeiro e 5 do segundo, mas não classificados todos em um, então eu tenho esse solução e alcançou exatamente o objetivo para mim mesmo, pelo menos

<?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
fonte