การรวมแบบสอบถามกับอาร์กิวเมนต์ที่แตกต่างกันต่อประเภทโพสต์


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) ได้หลอกลวง! ตอนนี้ฉันสามารถควบคุมสิ่งที่จะเกิดขึ้นในคิวรีสุดท้ายได้ก่อนที่จะเข้าไปในลูป ขอบคุณสำหรับความช่วยเหลือของคุณ!
Andy Merskin

1
อันแรกนั้นยาก แต่มีประสิทธิภาพมากกว่า (ในครั้งที่สองยังมีการสืบค้นฐานข้อมูล 2 ครั้ง) ฉันจะบอกว่ามันเป็นความชอบส่วนตัว
Mridul Aggarwal

จะสนใจอย่างมากในวิธีที่จะทำให้การแก้ปัญหาแรก! จำเป็นต้องใช้ตัวกรอง ฯลฯ มีการเรียกใช้UNIONการเรียงลำดับใน sql สำหรับแต่ละ post_type หรือไม่
โซโลมอน Closson

@SolomonClosson ตัวกรองนี้สามารถช่วยให้ - codex.wordpress.org/Plugin_API/Filter_Reference/posts_clauses
Mridul Aggarwal

7

@ ปกติ 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();?>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.