Posting Lengket melebihi posting per batas halaman

21

Saya menggunakan pre_get_postsuntuk menyesuaikan jumlah posting yang ditampilkan di beranda saya.

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

Tapi saya mengalami masalah dengan posting yang lengket. Pada dasarnya, jika saya memiliki posting yang lengket, kueri akan menampilkan lebih dari 12 posting yang telah saya tentukan, karena akan menampilkan 12 ditambah setiap posting yang lengket. Tentu saja saya bisa mengabaikan posting yang lengket:

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' );

Tapi saya rasa ini tidak ideal. Saya pikir posting lengket harus dimasukkan dalam batas 12 posting, dan tidak ditambahkan ke batas. Itulah yang paling masuk akal bagi saya. Apakah ada cara untuk mencapainya? Sudahkah saya membuat kesalahan yang layak pada wajah?

Cukup banyak duplikat: Tulisan Tempel & Posting Per Halaman tetapi anehnya ditutup karena terlalu terlokalisasi. Saya tidak setuju, jelas karena saya sedang mencari jawaban, tetapi juga karena itu adalah pertanyaan mengapa WordPress tampaknya tidak menghormati posts_per_page batas jika Anda menggunakan posting yang lengket. Jika Anda ingin 12 posting per halaman Anda harus mendapatkan 12, bukan 13, yang adalah apa yang akan Anda dapatkan jika Anda memiliki satu posting lengket.

helgatheviking
sumber

Jawaban:

12

Berikut adalah pendekatan untuk menghitung posting tempel dengan mendapatkan jumlah posting tempel (jika ada) dan memasukkannya ke dalam posts_per_pageparameter perhitungan :

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);
        }
    }
}

Edit

Dalam hal jumlah posting per halaman yang ingin kita atur kurang dari atau sama dengan jumlah posting yang lengket, saya telah mengaturnya posts_per_pagemenjadi satu dan itu akan menghasilkan 13 posting atau lebih $sticky_count + 1(dalam hal ini) hanya pada yang pertama halaman (halaman berikutnya akan memiliki 12 posting). Mungkin itu OK karena kasus ini jarang terjadi dan +1 pos di halaman pertama mungkin tidak terlalu signifikan.

Ini karena Wordpress akan menampilkan semua posting tempel pertama dan pada satu halaman (halaman pertama) bahkan jika jumlah mereka lebih besar dari posts_per_pageparameter, jadi kami mengatur posts_per_pagedalam hal ini ke jumlah minimal yang dimungkinkan 1, karena 0dan nilai negatif akan menonaktifkan yang posts_per_pageparameter dan yang akan membuat Wordpress untuk menampilkan semua posting di halaman pertama.

Ahmad M
sumber
Besar!! Saya pikir Anda perlu untuk mengubah $sticky_count + (12 - $sticky_count)ke 12- $sticky_countsekalipun. Sebagai contoh jika saya memiliki 1 sticky, maka matematika Anda masih bekerja sampai 12, dan kemudian WP menambahkan sticky post menjadi 13. Oh, dan jika if ($sticky_count > $posts_per_page)dan kami menetapkan ke 12, bukankah itu berarti kami akan menampilkan 24+?
Helgatheviking
@helgatheviking: Anda benar. Saya selalu melakukan kesalahan konyol, perhitungan tidak pernah menarik bagi saya. Dan ya, itu akan menghasilkan 24 posting. Saya telah memperbarui kode ke akun untuk itu, dan saya menambahkan cek untuk nomor halaman. Ini berfungsi dengan baik, tetapi sekarang akan ada satu kasus di mana $posts_per_pageakan sama dengan $sticky_count, dan di sini saya menetapkan parameter posts_per_page menjadi 1, dan saya pikir akan baik-baik saja karena kasus ini mungkin langka dan hanya akan ada di halaman pertama ( $sticky_count + 1).
Ahmad M
Terima kasih untuk hasil editnya! Saya pikir ini adalah solusi terbaik yang bisa kami peroleh dengan menggunakan posting yang lengket. Saya berpikir bahwa saya mungkin pada akhirnya akan mengurutkan berdasarkan kunci meta sederhana untuk melihat apakah suatu posting ditampilkan atau tidak. Itu berperilaku lebih normal untuk pemahaman saya.
helgatheviking
ini gagal sebagai solusi jika postingan lengket adalah bagian dari posts_per_page yang awalnya diinginkan. Jumlah total posting akan berkurang tetapi posting yang lengket tidak akan mendorong nomor itu kembali karena mereka adalah bagian dari tanggal yang diatur urutan normal.
Andrew Killen
3

Ada masalah jika posting yang lengket ada di halaman pertama.

Solusinya adalah dengan mengurangi jumlah posting sticky untuk posting sticky yang merupakan bagian dari halaman pertama.

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'  );

Saya harap ini akan membantu

csag
sumber
1
Apakah Anda yakin tidak ada solusi yang lebih mudah dan lebih cepat untuk itu? Petunjuk: Anda tahu jumlah posting lengket dan posting per halaman ...
kaiser
Saya tidak menemukan yang lebih baik sejauh ini .. Ini lebih merupakan perbaikan untuk sesuatu yang seharusnya ada di inti WP menurut saya
csag
Jika itu akan menjadi inti, skenario lain tidak akan berfungsi.
kaiser
Ini adalah bug yang diketahui dan dilacak di core.trac.wordpress.org/ticket/27282
Will.
@kaiser Ahmad M's solusi tidak memperhitungkan posting lengket yang akan muncul di halaman pertama terlepas dari keadaan lengket mereka. Ini dapat mengakibatkan terlalu sedikit posting yang muncul di halaman pertama (WordPress v4.9.7). Jawaban ini lebih baik karena memperhitungkan hal itu.
Jacob Budin
0

Saya membersihkan kedua jawaban di atas menjadi satu sehingga tidak memuat WP_Query yang tidak perlu, memperbaiki jika lengket pada halaman pertama, mengurangi waktu untuk memproses informasi dengan kode lebih cepat bersih.

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' );
Andrew Killen
sumber