I've setup a blog on an older site and have tried everything to get the pagination to work.
Here is the code from the category-blog.php file:
<section>
<div id="content">
<h1 class="blog-heading">In The News</h1>
<?php
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
get_posts(array(
'post_type' => 'post', // You can add a custom post type if you like
'paged' => $paged,
'posts_per_page' => 4
));
?>
<?php if( have_posts() ): ?>
<div id="blog-grid">
<?php while (have_posts()) : the_post(); ?>
<div class="blog-post" id="blog-post-<?php get_the_ID(); ?>">
<a href="<?php the_permalink(); ?>"><?php the_post_thumbnail( 'blog-index' ); ?></a>
<h1><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h1>
<?php the_excerpt(); ?>
<div class="readmore-link">
<a href="<?php the_permalink(); ?>">Read More</a>
</div><!-- end div.readmore-link -->
</div><!-- end div.blog-post -->
<?php endwhile; ?>
</div><!-- end div#blog-grid -->
<div class="pagination">
<?php my_pagination(); ?>
</div><!-- /.navigation -->
<?php endif; ?>
</div><!-- end content -->
</section>
and the functions.php file
if ( ! function_exists( 'my_pagination' ) ) :
function my_pagination() {
global $wp_query;
$big = 999999999; // need an unlikely integer
$paginate_links = paginate_links( array(
//'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
'base' => str_replace( $big, '%#%', get_pagenum_link($big) ),
'format' => '?paged=%#%',
'current' => max( 1, get_query_var('paged') ),
'total' => $wp_query->max_num_pages,
'prev_next' => False
) );
if ( $paginate_links ) {
echo $paginate_links;
}
}
endif;
When I access the blog page at /blog I can see the listing of posts.. as expected. The pagination renders below the posts (again, as expected) but when you navigate to, say, page 2.. you go to /blog/page/2/ and get a 404 error stating $post is not defined!
I've tried to overcome this with every post I could find online, from declaring posts_per_page and pre_get_posts in the functions.php like:
define('PER_PAGE_DEFAULT', 4);
function my_post_count_queries( $query ) {
if (!is_admin() && $query->is_main_query()){
$query->set('posts_per_page', 4);
}
}
add_action( 'pre_get_posts', 'my_post_count_queries' );
add_action( 'pre_get_posts', 'modify_blog_query' );
function modify_blog_query( $query ) {
if ( !is_admin() && $query->is_main_query() ) {
$query->set( 'posts_per_page', 4 );
}
}
function change_posts_per_page(){ return 1; }
if( preg_match("|\/".get_option('tag_base')."\/.+\/page\/[0-9]+$|i", $_SERVER['REQUEST_URI']) ){
add_filter( 'pre_option_posts_per_page' , 'change_posts_per_page');
}
and even going to far as modify the .htaccess rewrite rules to ignore the /blog pages.. I even installed a couple plugins, which rendered the pagination as my function does.. and still resulted in a 404.
I've also replaced the entire pagination function with standard Prev/Next, with the same results:
<div class="nav-previous alignleft"><?php next_posts_link( 'Older posts' ); ?></div>
<div class="nav-next alignright"><?php previous_posts_link( 'Newer posts' ); ?></div>
Lastly, since this is an existing, live site.. I cannot disable any existing plugins to see if one or more are causing a conflict or error.
Any help and feedback on the best/a better way to do this, is greatly appreciated.
UPDATED
I replaced the get_posts query with a custom query.. based on Nathan's recommendation below (thanks for that!).. still, same 404 on pagination links.
Here is the custom query I used:
<?php
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$temp = $wp_query;
$wp_query = null;
$wp_query_args = array(
'post_type'=> 'post',
'posts_per_page' => 4,
'paged'=> $paged
);
$wp_query = new WP_Query( $wp_query_args );
if ( $wp_query->have_posts() ) : ?>
<div id="blog-grid">
<?php while ( $wp_query->have_posts() ) : $wp_query->the_post(); ?>
<div class="blog-post" id="blog-post-<?php get_the_ID(); ?>">
<a href="<?php the_permalink(); ?>"><?php the_post_thumbnail( 'blog-index' ); ?></a>
<h1><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h1>
<?php the_excerpt(); ?>
<div class="readmore-link">
<a href="<?php the_permalink(); ?>">Read More</a>
</div><!-- end div.readmore-link -->
</div><!-- end div.blog-post -->
<?php endwhile; ?>
</div><!-- end div#blog-grid -->
<?php endif; ?>
<div class="pagination">
<?php my_pagination(); ?>
</div><!-- /.navigation -->
<?php
$wp_query = null;
$wp_query = $temp; // Reset
?>
SECOND UPDATE
This page is live, so I'm providing a link for those willing to help, to test with:
After a ton of research, fiddling and coding.. I realized that the pagination function was not adding the category base to the link - eg. /category/blog/ and only returning /bog/ ... oddly enough, the /blog page worked... but, when paging, it didn't.
So, I created a new template and renamed the category. I installed WP_PageNavi and used that for pagination. That resolved the issue.. so, this pagination function that's floating around, that a lot of people seem to be using, is not working properly.
Namely, this one:
It will not prepend the category base path.. which causes the pagination to fail the redirect.