web-dev-qa-db-fra.com

Comment faire fonctionner la pagination pour get_posts () dans WordPress?

Je travaille sur un site WordPress et j'ai créé un modèle de page qui affiche les publications par un slug de catégorie. Pour ce faire, je crée un champ pour la page, WP_Catid, et le définit égal au slug de catégorie à partir duquel je souhaite afficher les publications. Cependant, je ne souhaite que cinq publications par page avec des liens de pagination au bas de ces publications. Comment puis-je afficher correctement les liens de pagination?

Mon code est le suivant:

<div id="container">
  <div id="content" role="main">
    <?php
      $btpgid=get_queried_object_id();
      $btmetanm=get_post_meta( $btpgid, 'WP_Catid','true' );
      $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;

      $args = array( 'posts_per_page' => 5,
                     'category_name' => $btmetanm,
                     'paged' => $paged,
                     'post_type' => 'post' );

      $myposts = get_posts( $args );
      foreach ( $myposts as $post ) : setup_postdata( $post ); 
        echo "<div style='border:2px groove black; margin-bottom:5px;'><h3 class='btposth'>";
        the_title(); 
        echo "</h3><div class='btpostdiv'>";
        the_content();
        echo "</div></div>";
      endforeach; 
      next_posts_link( 'Older Entries'); //not displaying
      previous_posts_link('Newer Entries &raquo;'); //not displaying
      wp_reset_postdata();
    ?>
  </div><!-- #content -->
</div><!-- #container -->
18
B_Troutman

Pour faire court, n'utilisez pas get_posts si vous avez besoin de requêtes paginées. get_posts Fonctionne parfaitement si vous allez utiliser une requête personnalisée qui n'a pas besoin de pagination, mais cela devient vraiment un gros gâchis compliqué lorsque vous devez introduire la pagination.

Je pense que le plus simple et le plus approprié ici est d'utiliser WP_Query pour construire votre requête personnalisée, c'est-à-dire si vous ne pouvez pas utiliser pre_get_posts pour modifier la requête principale pour obtenir la sortie souhaitée de la requête principale.

Je pense que next_posts_link() et previous_posts_link() est préférable d'utiliser avec une requête personnalisée, c'est-à-dire avec WP_Query . Cependant, vous devez simplement vous rappeler de définir le paramètre $max_pages Lorsque vous utilisez une requête personnalisée, sinon votre pagination se brisera

Avec quelques ajustements mineurs, votre requête devrait ressembler à ceci

<div id="container">
<div id="content" role="main">
<?php
$btpgid=get_queried_object_id();
$btmetanm=get_post_meta( $btpgid, 'WP_Catid','true' );
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;

$args = array( 'posts_per_page' => 5, 'category_name' => $btmetanm,
'paged' => $paged,'post_type' => 'post' );
    $postslist = new WP_Query( $args );

    if ( $postslist->have_posts() ) :
        while ( $postslist->have_posts() ) : $postslist->the_post(); 


             echo "<div style='border:2px groove black; margin-bottom:5px;'><h3 class='btposth'>";
                 the_title(); 
             echo "</h3><div class='btpostdiv'>";
                 the_content();
             echo "</div></div>";

         endwhile;  

             next_posts_link( 'Older Entries', $postslist->max_num_pages );
             previous_posts_link( 'Next Entries &raquo;' ); 
        wp_reset_postdata();
    endif;
    ?>

</div><!-- #content -->
</div><!-- #container -->
37
Pieter Goosen

réponse de Pieter Goosen est tout à fait correct, et sa suggestion d'utiliser WP_Query a plutôt le sens. Cependant, je suis tombé sur cette question tout en recherchant la pagination avec get_posts en dehors de la boucle, j'ai donc pensé que cela pourrait aussi être une alternative utile pour n'importe qui d'autre:

get_posts a une propriété directe appelée offset qui réalise à peu près la même chose que paged dans WP_Query; mais où paged fait référence à la pagination (par exemple 1, 2, 3 ), offset est le réel nombre de publications par lesquelles vous souhaitez compenser votre requête (par exemple 5, 10, 15 ). Avec un peu de maths - numberToShow * pageNumber - vous pouvez facilement obtenir le bon décalage:

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

$postsPerPage = 5;
$postOffset = $paged * $postsPerPage;

$args = array(
    'posts_per_page'  => $postsPerPage,
    'category_name'   => $btmetanm,
    'offset'          => $postOffset,
    'post_type'       => 'post'
);

$myposts = get_posts($args);

La valeur initiale de paged dans cet exemple est 0 plutôt que 1 car, lors de la multiplication du posts_per_page, vous voulez que le décalage initial soit 0 plutôt que 5.

Cela peut être très pratique si vous voulez un contrôle un peu plus granulaire plutôt qu'une pagination simple, mais cela devrait aussi bien fonctionner en combinaison avec la boucle dans la réponse acceptée.

15
indextwo

Essayez de changer vos $ args:

$args = array( 
'posts_per_page' => 5,
'category_name' => $btmetanm,
'post_type' => 'post',
'paged' => ( get_query_var('paged') ? get_query_var('paged') : 1 )
   );

Et juste après la boucle, mettez ceci:

if (function_exists('wp_pagenavi')) {
wp_pagenavi();
}
4
hamza

Je ne vous dirai pas que l'utilisation de get_posts () est la bonne chose à faire ... mais voici un code de pagination de base que j'ai configuré en utilisant get_posts ().

EDIT: Comme l'a souligné Pieter, ce n'est pas destiné à être utilisé dans le code de production. Mais juste quelque chose avec lequel je jouais de toute façon pour voir si je pouvais faire fonctionner la pagination avec get_posts (). Si vous êtes dans un environnement de production, vous ne voudriez pas l'utiliser.

$cpt_name = 'post-type'; //add your own post type

//what pagination page are we on?
if(! empty($_GET['pag']) && is_numeric($_GET['pag']) ){
    $paged = $_GET['pag'];
}else{
    $paged = 1;
}
//you could use this if you want, just make sure to use "/page/2" instead of "?pag=2" in the pagination links.
//$paged = (get_query_var('paged')) ? get_query_var('paged') : 0;

//how many posts should we display?
$posts_per_page = (get_option('posts_per_page')) ? get_option('posts_per_page') : 10; 

//let's first get ALL of the possible posts
$args = array(
        'posts_per_page'   => -1,
        'orderby'          => 'title',
        'order'            => 'ASC',
        'fields'           => 'ids',
        'post_type'        => $cpt_name
    );

$all_posts = get_posts($args);

//how many total posts are there?
$post_count = count($all_posts);

//how many pages do we need to display all those posts?
$num_pages = ceil($post_count / $posts_per_page);

//let's make sure we don't have a page number that is higher than we have posts for
if($paged > $num_pages || $paged < 1){
    $paged = $num_pages;
}

//now we get the posts we want to display
$args = array(
        'posts_per_page'   => $posts_per_page,
        'orderby'          => 'title',
        'order'            => 'ASC',
        'post_type'        => $cpt_name,
        'paged'        => $paged
    );

$my_posts = get_posts($args);

//did we find any?
if(! empty($my_posts)){

    echo '<div id="my-posts-wrapper">';

    //THE FAKE LOOP
    foreach($my_posts as $key => $my_post){
                //do stuff with your posts
        echo '<div class="my-post">'.$my_post->post_title.'</div>';

    }

    echo '</div>';

    //we need to display some pagination if there are more total posts than the posts displayed per page
    if($post_count > $posts_per_page ){

        echo '<div class="pagination">
                <ul>';

        if($paged > 1){
            echo '<li><a class="first" href="?pag=1">&laquo;</a></li>';
        }else{
            echo '<li><span class="first">&laquo;</span></li>';
        }

        for($p = 1; $p <= $num_pages; $p++){
            if ($paged == $p) {
                echo '<li><span class="current">'.$p.'</span></li>';
            }else{
                echo '<li><a href="?pag='.$p.'">'.$p.'</a></li>';
            }
        }

        if($paged < $num_pages){
            echo '<li><a class="last" href="?pag='.$num_pages.'">&raquo;</a></li>';
        }else{
            echo '<li><span class="last">&raquo;</span></li>';
        }

        echo '</ul></div>';
    }
}

J'espère que quelqu'un en tirera profit :)

EDIT: Que diable! Aller faire quelque chose dans le mauvais sens ... autant le faire correctement! Voici aussi MOINS (sans aucun mixin).

.pagination             { margin: 30px 0px;
    ul                    { display:block; list-style-type:none; margin:0 auto; padding: 0px; 
      li                  { display:inline-block; list-style-type:none; margin:0; padding:0;
        a, span           { display:inline-block; font-size: 14px; width:auto; min-width:26px; height:26px; line-height: 26px; border: 1px solid #dddddd; border-right: 0px; background:#FFFFFF; color:#FF0000; padding: 5px; text-align: center;
          &:hover         { cursor:pointer; text-decoration:none; }

          &.first         { border-top-left-radius: 3px; border-bottom-left-radius: 3px; }
          &.last          { border-top-right-radius: 3px; border-bottom-right-radius: 3px;}
        }

        span.last,
        span.first        { color: #FF0000;
            &:hover       { cursor: default; }
        }

        a.last,
        a.first           { 
            &:hover       {  }
        }

        a:hover, 
        &.active a, 
        .current          { background:#FF0000; color:#ffffff; border-color: #b21712; }

        &:last-child      { 
            a, span       { border-right: 1px solid #dddddd; }

            a             { 
                &:hover   { border-color: #FF0000; }
            }
        }
      }
    }
}
2
Bullyen