Sticky Posts überschreiten das Seitenlimit

21

Ich ändere mit pre_get_postsdie Anzahl der auf meiner Homepage angezeigten Beiträge.

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

Aber ich habe ein Problem mit klebrigen Beiträgen. Grundsätzlich werden in der Abfrage mehr als die von mir angegebenen 12 Posts angezeigt, wenn ich irgendwelche klebrigen Posts habe, da 12 plus alle klebrigen Posts angezeigt werden . Ich könnte natürlich auch klebrige Beiträge ignorieren:

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

Aber ich halte das nicht für ideal. Ich denke , dass die klebrigen Beiträge werden sollten enthalten in der Grenze von 12 Stellen, und nicht hinzugefügt bis an die Grenze. Das macht für mich am meisten Sinn. Gibt es einen Weg, das zu erreichen? Habe ich einen Fehler gemacht, der Gesicht und Hand verdient?

Ziemlich genau ein Duplikat von: Sticky Posts & Posts pro Seite, aber das wurde seltsamerweise als zu lokalisiert geschlossen. Ich bin nicht einverstanden, offensichtlich, weil ich nach einer Antwort suche, aber auch, weil es eine Frage ist, warum WordPress das posts_per_page Limit nicht einzuhalten scheint, wenn Sie klebrige Beiträge verwenden. Wenn Sie 12 Posts pro Seite haben möchten, sollten Sie 12 erhalten, nicht 13, was Sie erhalten würden, wenn Sie einen einzelnen klebrigen Post hätten.

helgatheviking
quelle

Antworten:

12

Hier ist ein Ansatz, um klebrige Beiträge zu berücksichtigen, indem die Anzahl der klebrigen Beiträge (falls vorhanden) ermittelt und diese in den Berechnungsparameter posts_per_pageeinbezogen werden:

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

Bearbeiten

In dem Fall, in dem die Anzahl der Posts pro Seite, die wir festlegen möchten, kleiner oder gleich der Anzahl der Sticky-Posts ist, habe ich den Wert posts_per_pageauf 1 festgelegt, und dies führt zu 13 oder mehr Posts $sticky_count + 1(in diesem Fall) nur für den ersten Seite (nachfolgende Seiten haben 12 Beiträge). Vielleicht ist das in Ordnung, da dieser Fall selten vorkommt und ein Beitrag auf der ersten Seite möglicherweise nicht so aussagekräftig ist.

Dies liegt daran, dass Wordpress alle Haftnotizen zuerst und auf einer Seite (der ersten Seite) anzeigt, auch wenn die Anzahl der posts_per_pageHaftnotizen größer als der Parameter ist. posts_per_pageIn diesem Fall setzen wir den Wert auf den minimal möglichen Wert 1, da 0und negative Werte deaktiviert werden der posts_per_pageParameter und das veranlasst Wordpress, alle Beiträge auf der ersten Seite anzuzeigen.

Ahmad M
quelle
Groß!! Ich glaube , Sie müssen sich ändern $sticky_count + (12 - $sticky_count)zu 12- $sticky_countthough. Wenn ich zum Beispiel 1 Sticky habe, dann berechnet Ihre Mathematik immer noch 12 und WP fügt den Sticky Post hinzu, um 13 zu machen. Oh, und wenn if ($sticky_count > $posts_per_page)und wir auf 12 setzen, heißt das nicht, dass wir 24+ zeigen werden?
Helgatheviking
@helgatheviking: du hast recht. Ich mache immer so dumme Fehler, Berechnungen waren für mich nie so interessant. Und ja, das würde zu 24 Beiträgen führen. Ich habe den Code aktualisiert, um dem Rechnung zu tragen, und ich habe einen Scheck für eine Seitenzahl hinzugefügt. Dies funktioniert gut, aber jetzt wird es einen Fall $posts_per_pagegeben, in dem gleich ist $sticky_count, und hier setze ich den Parameter posts_per_page auf 1 und denke, dass dies in Ordnung ist, da dieser Fall vielleicht selten ist und sich nur auf der ersten Seite befindet ( $sticky_count + 1).
Ahmad M
Danke für die Bearbeitung! Ich denke, dies ist die beste Lösung, die wir mit Haftnotizen bekommen können. Ich denke, dass ich eventuell anhand eines einfachen Metaschlüssels sortieren könnte, ob ein Beitrag vorgestellt wird oder nicht. Das verhält sich nach meinem Verständnis normaler.
Helgatheviking
Dies schlägt als Lösung fehl, wenn die klebrigen Beiträge Teil der ursprünglich gewünschten posts_per_page sind. Die Gesamtzahl der Beiträge wird reduziert, aber die klebrigen Beiträge werden diese Anzahl nicht zurückschieben, da sie Teil des normalen Bestelldatums sind.
Andrew Killen
3

Es gibt ein Problem, wenn die Haftnotizen auf der ersten Seite sind.

Die Lösung besteht darin, die Anzahl der Haftnotizen für die Haftnotizen, die Teil der ersten Seite sind, zu verringern.

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

Ich hoffe es wird helfen

csag
quelle
1
Sind Sie sicher, dass es dafür keine einfachere und schnellere Lösung gibt? Tipp: Du kennst die Anzahl der Sticky Posts und die Posts pro Seite ...
kaiser
Besseres habe ich bisher nicht gefunden. Dies ist meiner Meinung nach eher ein Fix für etwas, das im WP-Kern enthalten sein sollte
am
Wenn es im Kern wäre, würden andere Szenarien nicht funktionieren.
Kaiser
Dies ist ein bekannter Fehler und wird unter core.trac.wordpress.org/ticket/27282
Will verfolgt.
Die Lösung von @kaiser Ahmad M berücksichtigt keine Haftnotizen, die unabhängig von ihrem Haftnotizstatus auf der ersten Seite erscheinen würden. Dies kann dazu führen, dass auf der ersten Seite zu wenige Beiträge angezeigt werden (WordPress v4.9.7). Diese Antwort ist besser, weil sie das erklärt.
Jacob Budin
0

Ich habe beide oben genannten Antworten in einer bereinigt, damit keine unnötigen WP_Query geladen werden. Behebt, ob die erste Seite klebrig ist, und verringert die Zeit, um die Informationen mit saubererem, schnellerem Code zu verarbeiten.

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
quelle