web-dev-qa-db-fra.com

Modification de messages par page et décalage avec pre_get_posts

J'ai un filtre qui utilise pre_get_posts pour modifier le nombre de publications par page de 4 sur la page de renvoi de nouvelles à 8 sur toutes les autres pages (page 2, 3, etc.). Cependant, je ne semble pas avoir le décalage correct, ou quelque chose, parce que mon get_next_posts_page_link ne montre pas une page 3, même si elle existe si je vais à l'URL manuellement. Le décalage actuel est quelque chose que j'ai réussi à évoquer accidentellement. Je pensais que cela fonctionnait, car la page 2 était correcte, mais en ajoutant de nouveaux postes de test, j'ai réalisé que cela ne fonctionnait pas.

function page_2_posts_per_page_filter( $query ) {

    $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;

    if ( !is_admin() && $query->is_paged && $query->is_main_query() ) {

        $offset = 4 + (($paged - 2) * 8);
        $query->set( 'offset', $offset );
        $query->set( 'posts_per_page', 8 );

    } else if (!is_admin() && $query->is_main_query()) {

        $query->set( 'posts_per_page', 4 );

    }
    return;
}
add_action( 'pre_get_posts', 'page_2_posts_per_page_filter', 1 );

EDIT: SOLUTION

function page_2_posts_per_page_filter( $query ) {

    $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
    $offset = 4;

    if ( !is_admin() && $query->is_paged && $query->is_main_query() ) {

        $offset = (($paged - 1) * 8) - $offset;
        $query->set( 'posts_per_page', 8 );
        $query->set( 'offset', $offset );

    } else if (!is_admin() && $query->is_main_query()) {

        $query->set( 'posts_per_page', 4 );

    }
    return;
}
add_action( 'pre_get_posts', 'page_2_posts_per_page_filter');

function found_offset( $found_posts, $query ) {

    $offset = 4;

    if( !is_admin() && $query->is_main_query() ) {
        $found_posts = $found_posts + $offset;
    }
    return $found_posts;
}
add_action( 'found_posts', 'found_offset', 10, 2 );
3
evu

Voici une réponse que j'ai récemment faite à une autre question, la même que la vôtre. Étant donné que la réponse n'a jamais été votée ou acceptée, je ne pouvais pas marquer cette question comme une copie, alors j'ai supprimé la réponse dans l'autre message et je l'ai republiée ici.

Veuillez noter que certains points ne concernent pas ce problème et peuvent être ignorés. De plus, il vous suffira de faire quelques modifications sur les valeurs, car je n’ai rien changé dans le message original. Alors ne vous inquiétez pas des informations contenues dans la réponse ;-)

REPONSE REPOSEE

Ici est une légère variation d'une réponse que j'ai faite à propos du même scénario. Ce qui diffère ici, c'est que vous voulez moins posts_per_page à la première page

ÉTAPE 1

Supprimer query_posts . Vous ne devriez jamais utiliser query_posts

Remarque: Cette fonction n'est pas destinée à être utilisée par des plugins ou des thèmes. Comme expliqué plus tard, il existe de meilleures options plus performantes pour modifier la requête principale. query_posts () est une façon trop simpliste et problématique de modifier la requête principale d'une page en la remplaçant par une nouvelle instance de la requête. Il est inefficace (ré-exécute les requêtes SQL) et échouera carrément dans certaines circonstances (particulièrement lorsqu'il s'agit de pagination de publications).

Remplacez-le par la boucle par défaut

<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>

    <?php if ( 'regularproducts' == get_post_type()  ) : ?>

        //CONTENT HERE

    <?php endif; ?>

    <?php if ( 'wpsc-product' == get_post_type()  ) : ?>

        //CONTENT HERE

    <?php endif; ?>

<?php endwhile; endif; ?>

ÉTAPE 2

Utilisez pre_get_posts pour modifier la requête principale afin d'ajouter vos post_types personnalisés à la requête principale à afficher sur la page d'accueil.

ÉTAPE 3

Maintenant, obtenez le jeu d’options posts_per_page à partir de l’arrière-plan (qui doit être défini sur 300) et définissez également votre offset que nous allons utiliser. Ce sera 200 car vous aurez besoin de 100 posts sur la première page et de 300 sur le reste.

Si vous ne souhaitez pas modifier l'option posts_per_page, vous pouvez simplement définir la variable $ppg sur 300.

$ppg = get_option( 'posts_per_page' );
//$ppg = 300;
$offset = 200;

ÉTAPE 4

Sur la première page, vous devrez soustraire offset à posts_per_page

$query->set( 'posts_per_page', $ppp - $offset );

ÉTAPE 5

Vous devez appliquer votre offset à toutes les pages suivantes, sinon vous obtiendrez une répétition du dernier message de la page de la page suivante.

$offset = ( ( $query->query_vars['paged']-1 ) * $ppp ) - $offset;
$query->set( 'posts_per_page', $ppp );
$query->set( 'offset', $offset ); 

ÉTAPE 6

Enfin, vous devez ajouter votre décalage à found_posts sinon votre pagination n’affiche pas la dernière page.

REMARQUE: cette partie de code a été interrompue dans la page de recherche. Cette erreur est corrigée, voir le code mis à jour}

function homepage_offset_pagination( $found_posts, $query ) {
    $offset = 200;

    if( $query->is_home() && $query->is_main_query() ) {
        $found_posts = $found_posts + $offset;
    }
    return $found_posts;
}
add_filter( 'found_posts', 'homepage_offset_pagination', 10, 2 );

ALL TOGETHER

Voici à quoi ressemblera votre requête complète qui devrait aller dans functions.php

function tax_and_offset_homepage( $query ) {
  if ( !is_admin() && $query->is_home() && $query->is_main_query() ) {
    $query->set( 'post_type', array( 'regularproducts', 'wpsc-product' ) );

    $ppp = get_option( 'posts_per_page' );
//$ppp = 300;
    $offset = 200;
    if ( !$query->is_paged() ) {
      $query->set( 'posts_per_page', $ppp - $offset );
    } else {
      $offset = ( ( $query->query_vars['paged']-1 ) * $ppp ) - $offset;
      $query->set( 'posts_per_page', $ppp );
      $query->set( 'offset', $offset );
    }
  }
}
add_action('pre_get_posts','tax_and_offset_homepage');

function homepage_offset_pagination( $found_posts, $query ) {
    $offset = 200;

    if( $query->is_home() && $query->is_main_query() ) {
        $found_posts = $found_posts + $offset;
    }
    return $found_posts;
}
add_filter( 'found_posts', 'homepage_offset_pagination', 10, 2 );
5
Pieter Goosen