Объединение запросов с разными аргументами для каждого типа поста

11

Я создаю раздел на сайте, где объединяю два разных типа записей в один цикл, а затем отображаю их случайным образом. Проблема в том, что мне трудно найти способ ограничить количество постов для каждого типа.

Вот что я попробовал:

  • Один запрос с несколькими типами записей может быть выполнен с помощью массива:

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

    ... но не может быть ограничено определенным количеством сообщений для каждого типа.

  • Объединение двух массивов аргументов запроса перед запуском на нем 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 );
    

    Не повезло в этом. Что происходит, последняя переменная $quotesперезаписывает $photosи показывает только кавычки.

  • Объединение двух объектов WP_Query вместе через приведение типов:

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

... и так далее.

Возможно, я мог бы использовать SQL-запрос прямо к базе данных, но мне нужно иметь возможность комбинировать эти два отдельных типа записей для одного цикла, расположенного случайным образом, И ограниченного определенным количеством сообщений для каждого типа.

Спасибо за вашу помощь!

Энди Мерскин
источник

Ответы:

16

Одним из способов является настройка SQL-запроса, выполняемого с использованием posts_clausesили других подобных фильтров. Чтобы найти их, posts_clausesпоищите в «wp-includes / query.php» и просмотрите ряд фильтров непосредственно перед этой строкой. Вместе они способны настроить любую часть запроса

Другая вещь, которую вы можете сделать, это вручную объединить запрошенные записи в объектах

$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 );
Мридул Аггарвал
источник
Ваше второе решение (без SQL) сработало! Теперь у меня есть полный контроль над тем, что входит в этот последний запрос, прежде чем идти в цикл. Спасибо за вашу помощь!
Энди Мерскин
1
Первый сложный, но более эффективный (во втором еще 2 запроса к базе данных). Я бы сказал, что все сводится к личным предпочтениям
Мридул Аггарвал
Был бы чрезвычайно заинтересован в том, как сделать первое решение! Необходимые фильтры и т. Д. Требует ли это UNIONкакого-то вида в sql для каждого post_type?
Соломон Клоссон
@SolomonClosson этот фильтр может помочь
Аггарвал
7

@mridual aggarwal ваш ответ очень хороший, но, к сожалению, он на самом деле не объединяет 2, wp_queryа показывает только посты обоих в порядке, я имею в виду 5 постов из первого и 5 из второго, но не отсортирован все в одном, поэтому у меня есть это решение и оно точно достигло цели для себя, по крайней мере

<?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();?>
Аднан
источник