กระทู้ปักหมุดมีจำนวนโพสต์เกินขีด จำกัด ต่อหน้า


21

ฉันใช้pre_get_postsเพื่อปรับจำนวนโพสต์ที่แสดงบนหน้าแรกของฉัน

function lifelounge_query_adjust( $query ) {
    if ( is_home() ) {
        set_query_var( 'posts_per_page', 12 );
        return;
    }
}
add_filter( 'pre_get_posts', 'lifelounge_query_adjust' );

แต่ฉันพบปัญหากับการโพสต์เหนียว โดยทั่วไปถ้าฉันมีโพสต์ใด ๆ เหนียวแบบสอบถามจะแสดงมากขึ้นกว่า 12 โพสต์ผมได้ระบุไว้เพราะมันจะแสดง 12 บวกยังโพสต์ใด ๆ แน่นอนฉันไม่สนใจโพสต์เหนียว:

function lifelounge_query_adjust( $query ) {
    if ( is_home() ) {
        set_query_var( 'posts_per_page', 1 );
        set_query_var( 'ignore_sticky_posts', 1 );
        return;
    }
}
add_filter( 'pre_get_posts', 'lifelounge_query_adjust' );

แต่ฉันไม่คิดว่านี่จะเหมาะ ฉันคิดว่าโพสต์เหนียวควรรวมอยู่ในขีด จำกัด ของ 12 โพสต์และไม่ได้เพิ่มไว้ในขีด จำกัด นั่นคือสิ่งที่สมเหตุสมผลที่สุดสำหรับฉัน มีวิธีการที่จะบรรลุเป้าหมายนั้นหรือไม่? ฉันทำข้อผิดพลาดที่ควรค่าแก่การเผชิญหน้าหรือไม่?

ค่อนข้างซ้ำซ้อนของ: โพสต์เหนียว & โพสต์ต่อหน้าแต่นั่นก็ปิดอย่างแปลกประหลาดที่มีการแปลเกินไป ฉันไม่เห็นด้วยอย่างชัดเจนเพราะฉันกำลังมองหาคำตอบ แต่ก็เป็นเพราะมันเป็นคำถามว่าทำไม WordPress จึงไม่เคารพposts_per_page ขีด จำกัดถ้าคุณใช้ข้อความติดหนึบ ถ้าคุณต้องการ 12 โพสต์ต่อหน้าคุณควรได้ 12 ไม่ใช่ 13 ซึ่งเป็นสิ่งที่คุณจะได้รับถ้าคุณมีโพสต์เหนียว ๆ

คำตอบ:


12

นี่คือวิธีการบัญชีสำหรับการโพสต์เหนียวโดยการรับจำนวนโพสต์เหนียว (ถ้ามี) และรวมไว้ในposts_per_pageพารามิเตอร์การคำนวณ:

add_action('pre_get_posts', 'ad_custom_query');
function ad_custom_query($query) {

    if ($query->is_main_query() && is_home()) {

        // set the number of posts per page
        $posts_per_page = 12;
        // get sticky posts array
        $sticky_posts = get_option( 'sticky_posts' );

        // if we have any sticky posts and we are at the first page
        if (is_array($sticky_posts) && !$query->is_paged()) {

            // counnt the number of sticky posts
            $sticky_count = count($sticky_posts);

            // and if the number of sticky posts is less than
            // the number we want to set:
            if ($sticky_count < $posts_per_page) {
                $query->set('posts_per_page', $posts_per_page - $sticky_count);

            // if the number of sticky posts is greater than or equal
            // the number of pages we want to set:
            } else {
                $query->set('posts_per_page', 1);
            }

        // fallback in case we have no sticky posts
        // and we are not on the first page
        } else {
            $query->set('posts_per_page', $posts_per_page);
        }
    }
}

แก้ไข

ในกรณีที่จำนวนโพสต์ต่อหน้าที่เราต้องการตั้งค่ามีจำนวนน้อยกว่าหรือเท่ากับจำนวนโพสต์ปักหมุดฉันได้ตั้งค่าเป็นposts_per_pageหนึ่งและจะส่งผลให้มี 13 โพสต์หรือมากกว่า$sticky_count + 1(ในกรณีนี้) เฉพาะในครั้งแรก หน้า (หน้าถัดไปจะมี 12 โพสต์) อาจเป็นไปได้ว่าเนื่องจากกรณีนี้หายากและ +1 โพสต์ในหน้าแรกอาจไม่สำคัญ

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


ยิ่งใหญ่ !! ฉันคิดว่าคุณจำเป็นต้องเปลี่ยน$sticky_count + (12 - $sticky_count)ไป12- $sticky_countแม้ว่า ตัวอย่างเช่นถ้าฉันมี 1 หนืดคณิตศาสตร์ของคุณยังคงทำงานได้ถึง 12 และจากนั้น WP เพิ่มโพสต์ติดหนึบที่ทำให้เป็น 13 โอ้และถ้าif ($sticky_count > $posts_per_page)และเราตั้งค่าเป็น 12 นั่นหมายความว่าเราจะแสดง 24+ หรือไม่
helgatheviking

@helgatheviking: คุณพูดถูก ฉันทำผิดพลาดอยู่เสมอการคำนวณไม่เคยน่าสนใจสำหรับฉันเลย และใช่ว่าจะส่งผลให้ 24 โพสต์ ฉันได้อัปเดตรหัสไปยังบัญชีสำหรับสิ่งนั้นและฉันได้เพิ่มการตรวจสอบหมายเลขหน้า ใช้งานได้ดี แต่ตอนนี้จะมีกรณีหนึ่งที่$posts_per_pageจะเท่ากับ$sticky_countและที่นี่ฉันตั้งค่าพารามิเตอร์ posts_per_page เป็น 1 และฉันคิดว่าจะตกลงเพราะกรณีนี้อาจหายากและจะอยู่ในหน้าแรกเท่านั้น ( $sticky_count + 1)
Ahmad M

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

สิ่งนี้จะล้มเหลวในการแก้ไขหากโพสต์ติดหนึบเป็นส่วนหนึ่งของ posts_per_page ที่ต้องการเริ่มแรก จำนวนการโพสต์ทั้งหมดจะลดลง แต่การโพสต์แบบติดหนึบจะไม่ส่งกลับจำนวนดังกล่าวเนื่องจากเป็นส่วนหนึ่งของชุดวันที่ตามสั่งปกติ
Andrew Killen

3

มีปัญหาหากโพสต์เหนียวอยู่ในหน้าแรก

การแก้ปัญหาคือการลดจำนวนการโพสต์เหนียวสำหรับการโพสต์เหนียวที่เป็นส่วนหนึ่งของหน้าแรก

function fix_posts_per_page_with_sticky_posts( $query ) {

    if ( $query->is_main_query() ) {

        // set the number of posts per page
        $posts_per_page = 12;

        // get sticky posts array
        $sticky_posts = get_option( 'sticky_posts' );

        // get queried post ids array
        $ids = array();
        $args = array(
            'post_type' => 'post',
            'post_per_page' => $posts_per_page,
            'paged' => 1
        );

        $posts = get_posts( $args );

        foreach ( $posts as $post ) {
            $ids[] = $post->ID;
        }

        // if we have any sticky posts and we are at the first page
        if ( is_array( $sticky_posts ) && ! $query->is_paged() ) {

            // count the number of sticky posts
            $sticky_count = count( $sticky_posts );

            foreach ( $sticky_posts as $sticky_post ) {
                if ( in_array( $sticky_post, $ids ) ) {
                    // decrement sticky posts count if the sticky post in on the page
                    $sticky_count--;
                }
            }

            // and if the number of sticky posts is less than
            // the number we want to set:
            if ( $sticky_count < $posts_per_page ) {
                $query->set( 'posts_per_page', $posts_per_page - $sticky_count );

            // if the number of sticky posts is greater than or equal
            // the number of pages we want to set:
            } else {
                $query->set( 'posts_per_page', 1 );
            }

        // fallback in case we have no sticky posts
        // and we are not on the first page
        } else {
            $query->set( 'posts_per_page', $posts_per_page );
        }
    }
}
add_action( 'pre_get_posts', 'fix_posts_per_page_with_sticky_posts'  );

ฉันหวังว่ามันจะช่วย


1
คุณแน่ใจหรือว่าไม่มีวิธีแก้ปัญหาที่ง่ายกว่าและเร็วกว่านี้? คำแนะนำ: คุณรู้จำนวนโพสต์เหนียวและโพสต์ต่อหน้า ...
kaiser

ฉันไม่ได้พบดีขึ้นจนถึงตอนนี้ .. นี่คือการแก้ไขบางอย่างที่ควรจะอยู่ในแกนกลาง WP ในความคิดของฉัน
csag

ถ้ามันจะเป็นแกนหลักสถานการณ์อื่น ๆ จะไม่ทำงาน
ไกเซอร์

นี่เป็นข้อผิดพลาดที่รู้จักและถูกติดตามที่core.trac.wordpress.org/ticket/27282
Will

วิธีการแก้ปัญหาของ @kaiser Ahmad M ไม่ได้หมายถึงโพสต์เหนียวที่จะปรากฏในหน้าแรกโดยไม่คำนึงถึงสถานะเหนียวของพวกเขา มันอาจส่งผลให้โพสต์น้อยเกินไปที่ปรากฏบนหน้าแรก (WordPress v4.9.7) คำตอบนี้ดีกว่าเพราะมันคำนึงถึงสิ่งนั้น
Jacob Budin

0

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

function modify_main_query( $query ) {
   if ( ( $query->is_home() || is_front_page() ) && $query->is_main_query() ) {
         // set the number of posts per page
        $posts_per_page = 12;
        // get sticky posts array
        $sticky_posts = get_option( 'sticky_posts' );
        // if we have any sticky posts and we are at the first page
        if (is_array($sticky_posts) && !$query->is_paged()) {
            // make a second query to make sure the sticky posts will still work 
            // correctly when on the first page
            // Only reply with the ID's as that is all that is needed
            $args = [
                'post_type' => 'post',
                'post_per_page' => $posts_per_page,
                'paged' => 1,
                'fields' => 'ids'
            ];
            // Array flip to reduce the time taken by 
            // using isset and not in_array
            $posts = array_flip( get_posts( $args ) );

            // count the number of sticky posts
            $sticky_count = count($sticky_posts);

            // loop the posts from the 2nd query to see if the ID's of the sticky posts
            // sit inside it.
            foreach ( $sticky_posts as $sticky_post ) {
                if(isset($posts[$sticky_post])){
                    $sticky_count--;
                }
            }
            // and if the number of sticky posts is less than
            // the number we want to set:
            if ($sticky_count < $posts_per_page) {
               $query->set('posts_per_page', $posts_per_page - $sticky_count);
            } else {
                // if the number of sticky posts is greater than or equal
                // the number of pages we want to set:
                $query->set('posts_per_page', 1);
            }
        // fallback in case we have no sticky posts
        // and we are not on the first page
        } else {
            $query->set('posts_per_page', $posts_per_page);
        }
    } 
}

add_action( "pre_get_posts", 'modify_main_query' );
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.