2

This issue is in my index.php (although i'm thinking about moving this code to home.php instead). I have a custom WP_Query which shows some posts per page, specifying post types (i have a custom type which the main query was not able to show). I have 42 posts atm (it's the Wordpress theme unit plus something i wrote earlier) and i did set 3 posts per page, which means i should have 15 pages. But from the 6th page and forward, i get a 404 error.

Code in index.php

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

$args = array(
   'posts_per_page' => 3,
   'paged' => $paged,
   'post_type' => array('post', 'blog_post'),
);

$query = new WP_Query($args); ?>
<?php echo $query->max_num_pages ?>
<?php while ( $query->have_posts() ) : $query->the_post() ?>

<section class="article-container col-md-12">

<?php if (has_post_thumbnail()) the_post_thumbnail("post-thumbnail", array('class' => 'img-responsive col-md-5')); ?>
<article class="col-md-7">
<h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
<?php the_excerpt(); ?>
<a href="<?php the_permalink(); ?>" class="article-read-more">LEGGI TUTTO</a>
</article>
</section>
<?php endwhile;  ?>
<?php wp_reset_postdata(); ?>

<?php if (function_exists("pagination")) {
    pagination($query->max_num_pages);
} ?>

Pagination function (i customized it cause i wanted my markup)

function pagination($pages = '', $range = 4) {  
     $showitems = ($range * 2)+1;  

     global $paged;
     if(empty($paged)) $paged = 1;

     if($pages == '') {
         global $wp_query;
         $pages = $wp_query->max_num_pages;
         if(!$pages) {
             $pages = 1;
         }
     }   

     if(1 != $pages) {
         echo '<section class="text-center">';
         echo '<ul class="pagination">';

         if($paged > 2 && $paged > $range+1 && $showitems < $pages) echo "<li><a href='".get_pagenum_link(1)."'>&laquo; First</a></li>";
         if($paged > 1 && $showitems < $pages) echo "<li><a href='".get_pagenum_link($paged - 1)."'>&lsaquo; Previous</a></li>";

         for ($i=1; $i <= $pages; $i++) {
             if (1 != $pages &&( !($i >= $paged+$range+1 || $i <= $paged-$range-1) || $pages <= $showitems )) {
                 echo ($paged == $i)? "<li class=\"active\"><a href=\"#\">".$i."</a></li>":"<li><a href='".get_pagenum_link($i)."'>".$i."</a></li>";
             }
         }

         if ($paged < $pages && $showitems < $pages) echo "<li><a href=\"".get_pagenum_link($paged + 1)."\">Next &rsaquo;</a></li>";  
         if ($paged < $pages-1 &&  $paged+$range-1 < $pages && $showitems < $pages) echo "<li><a href='".get_pagenum_link($pages)."'>Last &raquo;</a></li>";

         echo "</ul>";
         echo "</section>";
     }
}

So, considering i cannot use the main query as it is and a solution with it doesn't apply, what can i do? Any help will be appreciated.

  • 404 is based on the results of the main query, you can't paginate a custom query beyond the number of pages in the main query. – Milo May 27 '17 at 16:38
  • @Milo That's a problem: i need the loop to show both common wp posts and my custom type ones, but main query looks like refusing it. Is it possible to solve this instead and use the main query? – Daniele Squalo May 27 '17 at 16:43
  • @DanieleSqualo have you tried modifying the main query instead of replacing it? – Tom J Nowell May 27 '17 at 17:12
  • @Milo I have figured out why custom queries have this problem :o just a matter of rewrite rules. Fixing them allows to use pagination without strange tricks – Daniele Squalo May 28 '17 at 0:15
3

The problem is that WordPress is executing the main query before your custom query (and the main query is based on the default post type only).

You can intercept the main query, modify it, and then use it like so

function add_blog_post_to_query( $query ) {
    if ( $query->is_home() && $query->is_main_query() ) {
        $query->set( 'post_type', array('post', 'blog_post') );
        $query->set( 'posts_per_page', 3 );
    }
}
add_action( 'pre_get_posts', 'add_blog_post_to_query' );

Then if you want to still use your custom pagination function you would call it like so

if ( function_exists( 'pagination' ) ) {
    global $wp_query;
    pagination( $wp_query->max_num_pages );
}

Now, instead of using your custom query, you can use the standard functions like so:

if ( have_posts() ) :

    /* Start the Loop */
    while ( have_posts() ) : the_post();

        // your markup here

    endwhile;

else :

    // no posts found

endif;
  • Going to try this. – Daniele Squalo May 27 '17 at 18:07
  • Thank you. This worked and even fixed some minor issues i had. – Daniele Squalo May 27 '17 at 18:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.