Yapışkan Gönderiler, sayfa sınırı başına gönderileri aştı


21

pre_get_postsAna sayfamda görüntülenen yayın sayısını ayarlamak için kullanıyorum .

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

Ama yapışkan mesajlarda sorun yaşıyorum. Temel olarak, eğer herhangi bir yapışkan yazı varsa, sorgu belirttiğim 12 yazıdan daha fazlasını gösterecektir, çünkü 12 artı herhangi bir yapışkan yazı gösterecektir . Elbette, yapışkan mesajları görmezden gelebilirim:

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

Ama bunun ideal olduğunu sanmıyorum. Yapışkan postaların 12 posta sınırına dahil edilmesi gerektiğini ve bu sınıra eklenmemesi gerektiğini düşünüyorum. Benim için en mantıklı olan bu. Bunu başarmanın bir yolu var mı? Avuç içi kadar değerli bir hata mı yaptım?

Neredeyse bir kopyası: Sayfa Başına Yapışkan Gönderiler ve Gönderiler ancak bu çok yerelleştirilmiş olarak garip bir şekilde kapandı. Açıkçası bir cevap aradığım için değil, aynı zamanda yapışkan yazılar kullanıyorsanız WordPress'in neden posts_per_page sınıra saygı göstermediği sorusu olduğu için aynı fikirde değilim . Sayfa başına 12 yazı istiyorsanız, 13'e değil 12'ye, bir tek yapışkan yazı olsaydı elde edeceğinize sahip olmalısınız.

Yanıtlar:


12

Yapışkan posta sayısını (varsa) yapışkan yazı sayısını alarak hesaplamak için bir yaklaşım aşağıdadır 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);
        }
    }
}

Düzenle

Ayarlamak istediğimiz sayfa başına düşen yayın sayısının yapışkan yayın sayısına eşit veya daha az olması durumunda posts_per_page, bir tanesini belirledim ve bu $sticky_count + 1yalnızca ilk etapta 13 veya daha fazla yazıyla sonuçlanacak (bu durumda) sayfa (sonraki sayfalarda 12 mesaj olacak). Belki de bu tamamdır, çünkü bu durum nadirdir ve ilk sayfada +1 gönderimi bu kadar önemli olmayabilir.

Bunun nedeni, Wordpress'in tüm yapışkan gönderileri önce ve bir sayfada (ilk sayfada) sayıları posts_per_pageparametreden daha büyük olsa bile posts_per_pagegöstereceği için, bu durumda mümkün olan en düşük miktara ayarladık 1, çünkü 0ve negatif değerler devre dışı bırakılacak. posts_per_pageparametre ve bu ilk sayfadaki tüm mesajları görüntülemek için Wordpress yapacaktır.


Harika!! Ben değiştirmek gerekmez düşünüyorum $sticky_count + (12 - $sticky_count)için 12- $sticky_countgerçi. Örneğin, 1 yapışkanlığım varsa, matematiğiniz hala 12'ye kadar çalışır ve WP yapışkan yazıyı 13 yapmak için ekler. Oh, ve eğer if ($sticky_count > $posts_per_page)12'ye set edersek, bu 24 + 'ı göstereceğimiz anlamına gelmez mi?
12'de

@helgatheviking: haklısın. Hep böyle aptalca hatalar yapıyorum, hesaplamalar benim için hiç bu kadar ilginç olmamıştı. Ve evet, bu 24 mesajla sonuçlanır. Bunu hesaba katacak kodu güncelledim ve bir sayfa numarası için bir kontrol ekledim. Bu iyi çalışıyor, ama şimdi $posts_per_pageeşit olacağı bir durum olacak $sticky_countve burada posts_per_page parametresini 1 olarak ayarlıyorum, ve bu dava çok nadir olabileceğinden ve bunun sadece ilk sayfada olacağına göre iyi olacağını düşünüyorum. $sticky_count + 1).
Ahmad M

Düzenleme için teşekkürler! Bence yapışkan yazıları kullanarak alabileceğimiz en iyi çözüm bu. Sonunda, bir gönderinin öne çıkıp çıkmadığı konusunda basit bir meta anahtar ile sıralayabileceğimi düşünüyorum. Bu benim anlayışım için daha normal davranıyor.
12'de 12:10

Bu, yapışkan yazılar başlangıçta istenen posts_per_page öğesinin bir parçasıysa çözüm olarak başarısız olur. Toplam posta sayısı azalır, ancak yapışkan postalar, sıralanan normal tarihin bir parçası olduklarından, bu numarayı geri itmezler.
Andrew Killen

3

Yapışkan yazılar ilk sayfada ise bir sorun var.

Çözüm, ilk sayfanın bir parçası olan yapışkan direkler için yapışkan direk sayısını azaltmaktır.

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

Umarım yardımcı olur


1
Bunun daha kolay ve daha hızlı bir çözüm olmadığından emin misin? İpucu: Yapışkan yazıların ve sayfa başına yazıların miktarını biliyorsunuz ...
kaiser

Şimdiye kadar daha iyi bir şey bulamadım .. Bu benim görüşüme göre WP çekirdeğinde olması gereken bir şey için daha fazla bir düzeltmedir
csag

Çekirdekte olsaydı, diğer senaryolar işe yaramazdı.
kaiser

Bu bilinen bir hatadır ve core.trac.wordpress.org/ticket/27282
.

@kaiser Ahmad M'in çözümü, yapışkanlık durumlarına bakılmaksızın ilk sayfada görünecek yapışkan postaları hesaba katmaz. İlk sayfada çok az mesaj görünmesine neden olabilir (WordPress v4.9.7). Bu cevap daha iyi çünkü bunu açıklıyor.
Jacob Budin

0

Yukarıdaki cevapların her ikisini de bir cevap olarak temizledim, böylece WP_Query'ye ihtiyaç duymaz, ilk sayfadaki yapışkan bilgiyi daha hızlı kodla işlemek için gereken zamanı azaltır.

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' );
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.