มีข้อสงสัยเกี่ยวกับวิธีการทำงานของแบบสอบถามหลักและแบบสอบถามแบบกำหนดเองในชุดรูปแบบที่กำหนดเองนี้หรือไม่


20

ฉันค่อนข้างใหม่ในการพัฒนาชุดรูปแบบ WordPress และฉันไม่ได้เป็น PHP (ฉันมาจาก Java และ C #) และมีสถานการณ์ต่อไปนี้ในชุดรูปแบบที่กำหนดเองนี้

อย่างที่คุณเห็นในหน้าแรกฉันแสดงส่วน (ชื่อArticoli ใน evidenza ) ครั้งแรกที่มีโพสต์เด่น (ฉันได้ติดตั้งโดยใช้แท็กเฉพาะ) และภายใต้มันมีพื้นที่อื่น (ชื่อUltimi Articoli ) ที่มีโพสต์ล่าสุด นั่นไม่ใช่โพสต์เด่น

ฉันจะใช้รหัสนี้:

<section id="blog-posts">

<header class="header-sezione">
        <h2>Articoli in evidenza</h2>
</header>

<!--<?php query_posts('tag=featured');?>-->

<?php
    $featured = new WP_Query('tag=featured');

    if ($featured->have_posts()) : 
            while ($featured->have_posts()) : $featured->the_post();
            /*
             * Include the post format-specific template for the content. If you want to
             * use this in a child theme, then include a file called called content-___.php
             * (where ___ is the post format) and that will be used instead.
             */
                 get_template_part('content', get_post_format());

             endwhile;
        wp_reset_postdata();
    else :
        // If no content, include the "No posts found" template.
        get_template_part('content', 'none');

    endif;
    ?>


<header class="header-sezione">
    <h2>Ultimi Articoli</h2>
</header>

<?php
// get the term using the slug and the tag taxonomy
$term = get_term_by( 'slug', 'featured', 'post_tag' );
// pass the term_id to tag__not_in
query_posts( array( 'tag__not_in' => array ( $term->term_id )));
?>

<?php
    if (have_posts()) :
        // Start the Loop.
        while (have_posts()) : the_post();

            /*
             * Include the post format-specific template for the content. If you want to
             * use this in a child theme, then include a file called called content-___.php
             * (where ___ is the post format) and that will be used instead.
             */
            get_template_part('content', get_post_format());

        endwhile;
    else :
        // If no content, include the "No posts found" template.
        get_template_part('content', 'none');

    endif;
    ?>

</section>

ใช้งานได้ดี แต่ฉันมีข้อสงสัยเกี่ยวกับคุณภาพของโซลูชันนี้และวิธีการทำงาน

ในการเลือกโพสต์เด่นทั้งหมดฉันใช้บรรทัดนี้ที่สร้างWP_Queryวัตถุใหม่ที่กำหนดคิวรีที่มีแท็กเฉพาะfeatured:

$featured = new WP_Query('tag=featured');

จากนั้นฉันทำซ้ำผลการค้นหานี้โดยใช้have_posts()วิธีการ

ดังนั้นจากสิ่งที่ฉันเข้าใจนี่ไม่ใช่แบบสอบถามหลักของ WordPress แต่เป็นคำถามใหม่ที่ฉันสร้างขึ้น จากสิ่งที่ฉันเข้าใจจะเป็นการสร้างแบบสอบถามใหม่ (ตามที่ทำ) ดีกว่าและไม่ใช้คิวรีหลักเมื่อฉันต้องการดำเนินการชนิดนี้

มันเป็นความจริงหรือว่าฉันขาดอะไรไป? ถ้าเป็นจริงคุณช่วยอธิบายฉันได้ไหมว่าทำไมมันถึงดีกว่าที่จะสร้างคิวรีแบบกำหนดเองใหม่และไม่แก้ไขคิวรีหลักของ Wordpress

ตกลงไปต่อ ฉันแสดงโพสต์ทั้งหมดที่ไม่มีแท็ก 'ที่โดดเด่น' หากต้องการทำสิ่งนี้ฉันใช้ข้อมูลโค้ดนี้ซึ่งในทางกลับกันจะแก้ไขคิวรีหลัก:

    <?php
    // get the term using the slug and the tag taxonomy
    $term = get_term_by( 'slug', 'featured', 'post_tag' );
    // pass the term_id to tag__not_in
    query_posts( array( 'tag__not_in' => array ( $term->term_id )));
    ?>

    <?php
        if (have_posts()) :
            // Start the Loop.
            while (have_posts()) : the_post();
                get_template_part('content', get_post_format());

            endwhile;
        else :
            // If no content, include the "No posts found" template.
            get_template_part('content', 'none');

        endif;
        ?>

ดังนั้นฉันคิดว่านี่เป็นสิ่งที่น่ากลัวมาก จริงป้ะ?

UPDATE:

ที่จะทำดำเนินการเดียวกันผมพบว่าฟังก์ชั่นนี้ (ในคำตอบที่ดีด้านล่าง) ที่ผมได้เพิ่มfunctions.php

function exclude_featured_tag( $query ) {
    if ( $query->is_home() && $query->is_main_query() ) {
        $query->set( 'tag__not_in', 'array(ID OF THE FEATURED TAG)' );
    }
}
add_action( 'pre_get_posts', 'exclude_featured_tag' );

ฟังก์ชั่นนี้มีตะขอที่เรียกว่าหลังจากสร้างวัตถุตัวแปรแบบสอบถาม แต่ก่อนที่จะเรียกใช้แบบสอบถามที่เกิดขึ้นจริง

ดังนั้นจากสิ่งที่ฉันเข้าใจจะใช้วัตถุแบบสอบถามเป็นพารามิเตอร์ป้อนข้อมูลและปรับเปลี่ยน (จริงกรอง) โดยเลือกโพสต์ทั้งหมดยกเว้นแท็กเฉพาะ (ในกรณีของฉันfeaturedโพสต์แท็ก)

ดังนั้นฉันจะใช้การค้นหาก่อนหน้า (อันที่เคยแสดงการโพสต์เด่น) กับฟังก์ชั่นนี้เพื่อแสดงเฉพาะโพสต์ที่ไม่โดดเด่นในชุดรูปแบบของฉันได้อย่างไร หรือฉันต้องสร้างแบบสอบถามใหม่

คำตอบ:


33

คำถามจริงของคุณนั้นโดยทั่วไปแล้วเมื่อใดที่จะเรียกใช้แบบสอบถามที่กำหนดเองและเมื่อใดจึงจะใช้ประโยชน์จากแบบสอบถามหลัก ให้แบ่งมันออกเป็นสามส่วน

ส่วนหนึ่ง

เมื่อใดจึงจะเรียกใช้คิวรีที่กำหนดเอง (นี่ไม่ใช่รายการที่ชัดเจน)

  • เพื่อสร้างแถบเลื่อนเนื้อหาที่กำหนดเอง

  • เพื่อสร้างพื้นที่เนื้อหาที่โดดเด่นในหน้า

  • ในหน้า template php หากคุณต้องการแสดงข้อความ

  • หากคุณต้องการเนื้อหาที่กำหนดเองในหน้าคงที่

  • แสดงโพสต์ที่เกี่ยวข้องเป็นที่นิยมหรือให้ข้อมูล

  • เนื้อหารองหรือเนื้อหาเสริมอื่น ๆ ที่อยู่นอกขอบเขตของการสืบค้นหลัก

เมื่อใดจึงจะใช้ประโยชน์จากแบบสอบถามหลัก

เพื่อแสดงเนื้อหาหลักบน

  • ในหน้าแรกของคุณและหน้าตั้งเป็นบล็อกในแบ็กเอนด์

  • หน้าเก็บถาวรทั้งหมดที่มีแม่แบบเช่น archive.php, category.php, author.php, taxonomy.php, tag.php และ date.php

  • อัปเดต:แสดงเนื้อหาที่กำหนดเองในหน้าจริงและหน้าคงที่ (ดูที่การใช้ pre_get_posts ในหน้าจริงและหน้าคงที่ )

ส่วนที่สอง

ในการเลือกโพสต์เด่นทั้งหมดฉันใช้บรรทัดนี้ที่สร้างวัตถุ WP_Query ใหม่ที่กำหนดคิวรีที่มีแท็กเฉพาะที่โดดเด่น:

ดังนั้นจากสิ่งที่ฉันเข้าใจนี่ไม่ใช่แบบสอบถามหลักของ WordPres แต่เป็นคำถามใหม่ที่ฉันสร้างขึ้น จากสิ่งที่ฉันเข้าใจดีกว่าคือสร้างแบบสอบถามใหม่ (ตามที่ทำ) และไม่ใช้คิวรีหลักเมื่อฉันต้องการดำเนินการชนิดนี้

แก้ไข. สิ่งนี้ไม่อยู่ในขอบเขตของการสืบค้นหลัก นี่เป็นเนื้อหารองหรือเนื้อหาเสริมซึ่งไม่สามารถสร้างได้ด้วยข้อความค้นหาหลัก คุณควรใช้อย่างใดอย่างหนึ่งWP_Queryหรือget_postsเพื่อสร้างแบบสอบถามที่กำหนดเองของคุณ

ไม่เคยใช้ query_postsเพื่อสร้างแบบสอบถามที่กำหนดเองหรือแม้แต่แบบสอบถามอื่น ๆ ความสำคัญของฉัน

หมายเหตุ:ฟังก์ชั่นนี้ไม่ได้หมายถึงการใช้งานโดยปลั๊กอินหรือธีม ตามที่อธิบายในภายหลังมีตัวเลือกที่ดีกว่าและมีประสิทธิภาพมากกว่าในการแก้ไขคิวรีหลัก query_posts () เป็นวิธีที่ง่ายเกินไปและเป็นปัญหาในการแก้ไขคิวรีหลักของหน้าเว็บโดยแทนที่ด้วยอินสแตนซ์ใหม่ของแบบสอบถาม มันไม่มีประสิทธิภาพ (เรียกใช้แบบสอบถาม SQL อีกครั้ง) และจะล้มเหลวทันทีในบางสถานการณ์ (โดยเฉพาะอย่างยิ่งเมื่อจัดการกับการแบ่งหน้าโพสต์)

กำลังเดินทางไป

ตกลงฉันจะแสดงโพสต์ทั้งหมดที่ไม่มีแท็กเด่นเพื่อทำสิ่งนี้ฉันใช้ข้อมูลโค้ดนี้ซึ่งในทางกลับกันแก้ไขเคียวรีหลัก:

query_posts( array( 'tag__not_in' => array ( $term->term_id )));

ดังนั้นฉันคิดว่านี่เป็นสิ่งที่น่ากลัวมาก จริงป้ะ?

นั่นคือทั้งหมดที่ผิดและคำสั่งของคุณเป็นจริงน่าเสียดาย ตามที่กล่าวมาก่อนไม่เคยquery_postsใช้ มันเรียกใช้แบบสอบถามใหม่ที่สมบูรณ์ซึ่งไม่ดีต่อประสิทธิภาพและในกรณีส่วนใหญ่จะแบ่งการแบ่งหน้าซึ่งเป็นส่วนสำคัญของแบบสอบถามหลักสำหรับการแบ่งหน้าเพื่อให้ทำงานได้อย่างถูกต้อง

นี่คือเนื้อหาหลักของคุณดังนั้นคุณควรใช้คิวรีหลักกับลูปเริ่มต้นซึ่งควรมีลักษณะเช่นนี้และนี่คือทั้งหมดที่คุณต้องการ

<?php
    if (have_posts()) :
        // Start the Loop.
        while (have_posts()) : the_post();

            get_template_part('content', get_post_format());

        endwhile;
    else :
        // If no content, include the "No posts found" template.
        get_template_part('content', 'none');

    endif;
?>

คุณสามารถกำจัดส่วนนี้ลบเขียนและลืมมันได้

<?
// get the term using the slug and the tag taxonomy
$term = get_term_by( 'slug', 'featured', 'post_tag' );
// pass the term_id to tag__not_in
query_posts( array( 'tag__not_in' => array ( $term->term_id )));
?>

ตกลงเมื่อคุณทำเช่นนั้นแล้วคุณจะเห็นว่าโพสต์จากแท็กคุณสมบัติปรากฏในหน้าแรกของคุณโดยใช้คิวรีหลักและลูปเริ่มต้น

pre_get_postsวิธีที่ถูกต้องในการลบแท็กนี้จากหน้าแรกอยู่กับ นี่คือวิธีการที่เหมาะสมในการปรับเปลี่ยนแบบสอบถามหลักและเบ็ดคุณควรเสมอใช้เพื่อให้การเปลี่ยนแปลงห่วงเนื้อหาหลักของคุณ

ดังนั้นรหัสที่pre_get_postsถูกต้องและนี่คือฟังก์ชั่นที่คุณควรใช้ มีเพียงสิ่งเดียวเท่านั้นให้ตรวจสอบเสมอว่าคุณไม่ได้อยู่ในหน้าผู้ดูแลระบบเพราะpre_get_postsจะเปลี่ยนส่วนหลังเช่นกัน ดังนั้นนี่คือรหัสที่เหมาะสมที่จะใช้ในfunctions.phpการลบโพสต์ที่ติดแท็กแนะนำจากหน้าแรก

add_action( 'pre_get_posts', 'exclude_featured_tag' );
function exclude_featured_tag( $query ) 
{
    if (    !is_admin() 
         && $query->is_home() 
         && $query->is_main_query() 
    ) {
        $query->set( 'tag__not_in', [ID OF THE FEATURED TAG] );
    }
}

ส่วนที่สาม

เนื้อหาการอ่านเพิ่มเติมซึ่งจะเป็นประโยชน์ในอนาคต


ด้วยความยินดี. ดีใจที่คุณพบว่ามันมีประโยชน์ Enjou :-)
Pieter Goosen

ว้าวค่อนข้างคำตอบ! ฉันไม่มีข้อมูลสำคัญชิ้นหนึ่ง: ฉันจะบอก WP ได้อย่างไร "นี่คือหน้าโพสต์" นอกเหนือจากหน้าโพสต์หลัก สมมติว่าฉันต้องการรายการหนึ่งโพสต์ที่มีหมวดหมู่ 10,11,12 และอีกหนึ่งรายการที่มีหมวดหมู่ 13,14,15 ฉันเห็นว่าฉันสามารถใช้ pre_get_posts เพื่อแทรกหมวดหมู่ลงในคิวรีหลักได้อย่างไร แต่ฉันจะบอกให้ WP แสดงผลนั้นเป็นรายการโพสต์ที่มีการแบ่งหน้าที่เหมาะสมได้อย่างไร ฉันต้องทำตามคำตอบมากมายของคุณที่นี่หรือไม่wordpress.stackexchange.com/a/215027/74134เพราะเป็นหน้าเว็บ แน่นอนว่า WordPress อนุญาตให้มีรายการบล็อกหลายรายการในเว็บไซต์ได้หรือไม่?
Mark Berry
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.