the_content และ is_main_query


15

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

เพื่อที่จะตอบโต้นั้นฉันใช้is_main_query()เพื่อกำหนดเป้าหมายของการสืบค้นหลักเท่านั้น แต่มันไม่ทำงาน การเปลี่ยนแปลงจะยังคงใช้กับการค้นหาทั้งหมดตลอดไป สิ่งที่ตลกคือการตรวจสอบตามเงื่อนไขอื่น ๆ ทั้งหมดis_single()และis_category()ทำงานได้ดีหากฉันกำหนดเป้าหมายไปยังหน้าเฉพาะยกเว้นการเปลี่ยนแปลงทั้งหมดจะมีผลกับข้อความค้นหาที่กำหนดเองอื่น ๆ ในหน้านั้นไม่ว่าฉันจะใช้is_main_query()หรือไม่ก็ตาม

ฉันพลาดอะไรบางอย่างที่นี่ ฉันจะนำการเปลี่ยนแปลงไปใช้กับการสืบค้นหลักโดยใช้the_contentตัวกรองได้อย่างไร

add_filter('the_content', 'custom_content');

function custom_content($content){

    if(is_main_query()){ // << THIS IS NOT WORKING
        // My custom content that I add to the_content()    
    }
    return $content;
}

คำตอบ:


11

ความซื่อสัตย์ฟังก์ชั่นin_the_loop()คือสิ่งที่คุณกำลังมองหา:

add_filter( 'the_content', 'custom_content' );

function custom_content( $content ) {
    if ( in_the_loop() ) {
        // My custom content that I add to the_content()    
    }
    return $content;
}

สิ่งที่in_the_loopจะตรวจสอบว่าทั่วโลกสำหรับ$wp_query(นั่นคือวัตถุแบบสอบถามหลัก) ของการโพสต์ปัจจุบันคือ-1 < $current_post < $post_countอะไร

ที่เกิดขึ้นเมื่อการสืบค้นหลักกำลังวนลูปเพราะก่อนที่ลูปจะเริ่มโพสต์ปัจจุบันคือ -1 และหลังจากลูปสิ้นสุดการโพสต์ปัจจุบันจะถูกรีเซ็ตเป็น -1 อีกครั้ง

ดังนั้นถ้าin_the_loop()เป็นจริงก็หมายความว่าวัตถุคิวรีหลักคือการวนซ้ำซึ่งเป็นสิ่งที่คุณต้องการในกรณีนี้ (และเป็นผลลัพธ์เดียวกันกับการเพิ่มการดำเนินการloop_startและลบออกloop_endเช่นคำตอบ @ialocin ที่เขียนจริง ๆ แล้วมันทำงานได้ ด้วยเหตุผลเดียวกันและรับ +1 ของฉัน)

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


ฉันไม่เจอการค้นหาไซต์หรือการค้นหาออนไลน์ในครั้งนี้ อัญมณีซ่อนเร้นที่ใช้งานได้ ทุกโซลูชันใช้is_main_queryจริง ๆ คิดว่าไม่มีใครทดสอบอย่างละเอียด ขอบคุณสำหรับการป้อนข้อมูลของคุณชื่นชมจริงๆ
Pieter Goosen

1
@PieterGoosen ดีใจที่ได้ผล นั่นคือฟังก์ชั่นที่เก่าแก่มากที่มาตรงจากเวลาที่is_main_queryไม่ได้เป็นอะไร
gmazzap

คุณเห็นนี่คือที่ที่ฉันพลาดฉันไม่ใช่ตัวจับเวลาเก่า :-) เข้าร่วม Wordpress ใน 3.3
Pieter Goosen

2
@GM คุณคิดจะเพิ่มคำตอบของคุณ นี่เป็นข้อมูลที่เป็นประโยชน์ต่อผู้อื่นที่อาจสะดุดเมื่อคำตอบนี้ คนส่วนใหญ่อย่างฉันไม่ได้อ่านความคิดเห็น :-)
Pieter Goosen

1
@PieterGoosen เรียบร้อยแล้ว :)
gmazzap

7

นี่เป็นเพียงส่วนเสริมจากคำตอบของ @ Otto เพียงเพื่อให้เข้าใจได้ดีขึ้นเล็กน้อย โดยพื้นฐานแล้วสิ่งที่ @Otto กำลังพูดคุณต้องย้อนกลับตรรกะนั่นหมายความว่า: หากคุณสามารถกำหนดข้อความค้นหาหลักได้อย่างน่าเชื่อถือคุณสามารถเพิ่ม - และนำออก - การเชื่อมโยงของคุณเข้ากับthe_contentตัวกรอง

ตัวอย่างเช่นคำถามหลักสามารถจดจำได้อย่างน่าเชื่อถือในการpre_get_postsดำเนินการดังนั้นสิ่งนี้จะได้ผล:

function wpse162747_the_content_filter_callback( $content ) {
    return $content . 'with something appended';
}

add_action( 'pre_get_posts', 'wpse162747_pre_get_posts_callback' );
function wpse162747_pre_get_posts_callback( $query ) {
    if ( $query->is_main_query() ) {
        add_filter( 'the_content', 'wpse162747_the_content_filter_callback' );
    }
}

ตามที่คุณควรจะเอาตัวกรองออกเมื่อไม่ต้องการใช้อีกต่อไปฉันคิดว่าการloop_endกระทำควรเป็นสถานที่ที่ดีสำหรับสิ่งนั้นและในฐานะที่เราสามารถใช้งานloop_startได้ ซึ่งจะมีลักษณะเช่นนี้:

add_action( 'loop_start', 'wpse162747_loop_start_callback' );
function wpse162747_loop_start_callback( $query ) {
    if ( $query->is_main_query() ) {
        add_filter( 'the_content', 'wpse162747_the_content_filter_callback' );
    }
}

add_action( 'loop_end', 'wpse162747_loop_end_callback' );
function wpse162747_loop_end_callback( $query ) {
    if ( $query->is_main_query() ) {
        remove_filter( 'the_content', 'wpse162747_the_content_filter_callback' );
    }
}

จะทดสอบวันพรุ่งนี้นี้ ขอบคุณสำหรับคำอธิบายโดยละเอียดของคุณ
Pieter Goosen

ความสุขของฉันเป็นเสมอ @PieterGoosen ไม่รีบ แต่ทำเพราะฉันไม่ได้ - อย่างน้อยก็ไม่เพียงพอ
นิโคไล

1
จะเกิดอะไรขึ้นหากมีการใช้รหัสย่อภายใน the_content () และรหัสย่อจะเริ่มการสืบค้นอื่นที่เรียก the_content () ให้รีเซ็ตวัตถุโพสต์ปัจจุบันและลูปจะดำเนินต่อไป ตัวกรองทั้งหมดจะนำไปใช้ ค่อนข้างยุ่งยากหากไม่ได้รับการบันทึกโดยกระดิ่ง in_the_loop () ... นั่นเป็นเหตุผลที่ฉันแนะนำให้ลบตัวกรองที่ไม่ซ้ำกันทันทีที่พวกเขาทำตามที่ได้รับการทาบทามโดย @Nicolai
Jonas Lundman

5

คุณกำลังใช้ is_main_query()ไม่ถูกต้อง ฟังก์ชั่นทั่วโลก is_main_query () ผลตอบแทนจริงเว้นแต่ตัวแปรทั่วโลก $ wp_query ได้รับการนิยามใหม่

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

แต่คุณควรเพิ่มตัวกรองของคุณเมื่อคุณต้องการแล้วลบออกเมื่อไม่ต้องการ


จริงๆแล้วเป็นการลดลงที่ไม่มีวิธีการที่ตรงไปตรงมาเพื่อกำหนดเป้าหมายการสืบค้นหลักด้วยthe_contentตัวกรอง
Pieter Goosen

นั่นไม่น่าแปลกใจจริงๆ เช่นเดียวกับตัวกรองอื่น ๆ มันเพียงกรองสิ่งต่าง ๆ ไม่ทราบบริบทโดยรอบเมื่อมันถูกเรียก มันอาจไม่ถูกเรียกจากภายในลูปที่เหมาะสม ไม่มีทางที่จะบอกได้
อ็อตโต
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.