投稿タイプごとに異なる引数を持つクエリを組み合わせる


11

2つの異なる投稿タイプを1つのループにマージし、それらをランダムに表示するサイトにセクションを構築しています。問題は、タイプごとの投稿を制限する方法を見つけるのに苦労していることです。

これが私が試したものです:

  • 複数の投稿タイプを持つ1つのクエリは、配列で実現できます。

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

    ...しかし、タイプごとの特定の数の投稿に制限することはできません。

  • WP_Queryを実行する前に、2つのクエリ引数配列をマージします。

    $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、引用符のみが表示されます。

  • 型キャストを介して2つの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クエリを使用することもできますが、これらの2つの別々の投稿タイプを1つのループに組み合わせ、ランダムに配置し、タイプごとに一定数の投稿に制限する必要があります。

ご協力いただきありがとうございます!

回答:


16

1つの方法は、posts_clausesなどのフィルターを使用して実行されるSQLクエリをカスタマイズすることです。それらを見つけるには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 );

2番目のソリューション(SQLなし)がうまくいきました!これで、ループに入る前に、最終クエリの内容を完全に制御できます。ご協力いただきありがとうございます!
Andy Merskin

1
最初のものは難しいですが、より効率的です(2番目にはまだ2つのデータベースクエリがあります)。それは個人的な好みに
よると思い

最初の解決策を達成する方法に非常に興味があります!必要なフィルターなど。これはUNION、各post_typeのsqlで何らかのソートを必要としますか?
ソロモンクロッソン2017年

@SolomonClossonこのフィルターは役立ちます-codex.wordpress.org/Plugin_API/Filter_Reference/posts_clauses
Mridul Aggarwal

7

@mridual aggarwalあなたの答えは非常に良いですが、残念ながらそれは本当に2つを組み合わせているわけではありません。wp_queryそれは、両方の投稿を並べ替えて表示しているだけです。ソリューション&それは正確に少なくとも私の自己の目標を達成しました

<?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();?>
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.