3

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.

4
  • 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, 2017 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? May 27, 2017 at 16:43
  • @DanieleSqualo have you tried modifying the main query instead of replacing it?
    – Tom J Nowell
    May 27, 2017 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 May 28, 2017 at 0:15

1 Answer 1

5

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;
3
  • Going to try this. May 27, 2017 at 18:07
  • Thank you. This worked and even fixed some minor issues i had. May 27, 2017 at 18:38
  • Saved my life, thank you, it's an awesome solution. :)
    – Jodyshop
    Sep 24, 2021 at 22:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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