web-dev-qa-db-fra.com

Postes collants dépassent le nombre de messages par page

J'utilise pre_get_posts pour ajuster le nombre de publications affichées sur ma page d'accueil.

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

Mais je rencontre un problème avec les posts collants. Fondamentalement, si j'ai des posts collants, la requête affichera plus que les 12 posts que j'ai spécifiés, car elle affichera 12 plus tous les posts collants. Bien sûr, je pourrais ignorer les posts collants:

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

Mais je ne pense pas que ce soit idéal. Je pense que les posts collants devraient être inclus dans la limite de 12 posts, et non ajouté à la limite. C'est ce qui me semble le plus logique. Y a-t-il un moyen d'y parvenir? Ai-je commis une erreur digne du visage?

Quasiment une copie de: Postes collants et messages par page mais cela a été étrangement fermé car trop localisé. Je ne suis pas d’accord, évidemment parce que je cherche une réponse, mais aussi parce que la question de savoir pourquoi WordPress ne semble pas respecter le posts_per_page limit si vous utilisez des posts collants. Si vous voulez 12 messages par page, vous devriez en obtenir 12, et non 13, ce que vous obtiendriez si vous n'aviez qu'un seul post collant.

21
helgatheviking

Voici une approche permettant de comptabiliser les posts collants en obtenant le nombre de posts collants (le cas échéant) et de l'inclure dans le paramètre de calcul 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);
        }
    }
}

Modifier

Dans le cas où le nombre de messages par page que nous souhaitons définir est inférieur ou égal au nombre de messages collants, j'ai défini le posts_per_page à un et il en résultera 13 ou plus messages $sticky_count + 1 (dans ce cas) uniquement le la première page (les pages suivantes auront 12 posts). C’est peut-être acceptable puisque ce cas est rare et que +1 post sur la première page n’est peut-être pas si significatif.

En effet, Wordpress affichera tous les posts collants en premier et sur une page (la première page) même si leur nombre est supérieur au paramètre posts_per_page. Nous définissons donc le posts_per_page dans ce cas avec la quantité minimale possible qui est 1, car 0 et les valeurs négatives désactivent le paramètre posts_per_page, ce qui obligera Wordpress à afficher tous les articles de la première page.

12
Ahmad M

Il y a un problème si les messages collants sont dans la première page.

La solution consiste à réduire le nombre de posts collants pour les posts collants faisant partie de la première page.

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

J'espère que cela aidera

3
csag

J'ai nettoyé les deux réponses ci-dessus en une seule afin qu'il ne charge pas WP_Query inutile, des corrections si le post-it de la première page réduisaient le temps nécessaire pour traiter les informations avec un code plus propre et plus rapide.

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