Поєднання запитів з різними аргументами на тип публікації


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-include / 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 запити до бази даних). Я б сказав, що це зводиться до особистих уподобань
Mridul Aggarwal

Буде надзвичайно зацікавлений у тому, як досягти першого рішення! Потрібні фільтри і т. Д. Чи це вимагає UNIONпевного типу в sql для кожного post_type?
Соломон Клоссон

@SolomonClosson цей фільтр може допомогти
codex.wordpress.org/

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();?>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.