0

The basic issue is that every paginated page for my blog is going to a 404 page. /page/2/, /page/3/, etc. It used to be working fine, but is not now. I think maybe the change to 3.9 did it.

Here are some of the many things I have tried in an effort to fix this. The end result of all of these were the same. The paginated links 404'd.

  • deactivated all plugins
  • removed and reset permalinks multiple times
  • tried permalinks as default rather than /postname
  • Ensured my Reading Settings > Blog pages show at most was set to the same number as my loop. (as well as more and less to test)
  • I tried two separate navigation plugins and the default wordpress pagination (older posts) and it 404s every time. tried using parse_query
  • tried paginate_links

Here is my code (or links to my code):

home.php

    <?php require dirname( __FILE__ ) . '/blog-page.php';

blog-page.php

<?php
/*
Template Name: Blog Page - Custom
*/

get_header(); ?>

<---CUSTOM CODE--->

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

$wp_query = new WP_Query($args);

if($wp_query->have_posts()) : 

   while($wp_query->have_posts()) : $wp_query->the_post(); ?>

<---CUSTOM CODE--->


   endwhile;

wp_reset_postdata();?>

<div class="nav-previous alignleft"><?php next_posts_link( 'Older posts' ); ?></div>
<div class="nav-next alignright"><?php previous_posts_link( 'Newer posts' ); ?></div>
<?php  endif; wp_reset_query();

If it helps, here is a test site I've set up with the page in question. I've left it off with the default wordpress pagination.

I've run out of things to try. Any suggestions would be appreciated.

3
  • I also tried this option here, but couldn't post the link tried this option here: wordpress.stackexchange.com/questions/54509/…
    – jphogan
    Commented Jun 9, 2014 at 20:56
  • 1
    why are you creating a new query in your template and not using the default main query?
    – Milo
    Commented Jun 9, 2014 at 21:20
  • 2
    You are not going to have reliable pagination with overriding main query in template. Never. Seriously.
    – Rarst
    Commented Jun 9, 2014 at 21:52

2 Answers 2

4

There are a couple of things I don't understand here, but I'll try answering them as I go along.

You have a home.php, which I assume is your default homepage. You have one line of code in there, and that is to call a another page template. Here is you code

  <?php require dirname( __FILE__ ) . '/blog-page.php'; 

In blog-page.php you have the complete page template. My question is, why are you doing this. Why not just add the content of blog-page.php into home.php? Would make more sense.

You are not using the main query to run your loop, but a custom one, which I also don't understand, as your custom query does exactly the same as the main query, except for posts per page. This whole custom query can be avoided by just using pre_get_posts to set a custom number of posts on your homepage.

function posts_on_homepage( $query ) {
    if ( $query->is_home() && $query->is_main_query() ) {
        $query->set( 'posts_per_page', '5' );
    }
}
add_action( 'pre_get_posts', 'posts_on_homepage' );

You can just add this into functions.php which will set your amount of posts on your homepage to 5, and then you can replace the custom query with a normal loop.

One thing to keep in mind here, whenever you run a custom query, pagination will fail as stated in the comments.

You will need to have a look at WP_Qeury's pagination parameters.

paged (int) - number of page. Show the posts that would normally show up just on page X when using the "Older Entries" link.

page (int) - number of page for a static front page. Show the posts that would normally show up just on page X of a Static Front Page.

So your query should look like this for normal pages

$paged = ( get_query_var('paged') ) ? get_query_var('paged') : 1;
$query = new WP_Query( array( 'paged' => $paged ) );

And like this for static pages

$paged = ( get_query_var('page') ) ? get_query_var('page') : 1;
$query = new WP_Query( array( 'paged' => $paged ) );

You are also resetting your postdata twice. You should only do that once. BTW wp_reset_query(); is wrong, it is only used for query_posts that should not be used. You should be using wp_reset_postdata();

Lastly, when using a custom query, you have to specify the maximum namber of pages for next_posts_link by using the $max_pages parameter, otherwise it will fail.

 next_posts_link( 'Older Entries', $the_query->max_num_pages );

Here is an example of a proper working custom query as from the codex

<?php
// set the "paged" parameter (use 'page' if the query is on a static front page)
$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;

// the query
$the_query = new WP_Query( 'cat=1&paged=' . $paged ); 
?>

<?php if ( $the_query->have_posts() ) : ?>

<?php
// the loop
while ( $the_query->have_posts() ) : $the_query->the_post(); 
?>
   <?php the_title(); ?>
<?php endwhile; ?>

<?php

// next_posts_link() usage with max_num_pages
next_posts_link( 'Older Entries', $the_query->max_num_pages );
previous_posts_link( 'Newer Entries' );
?>

<?php 
// clean up after our query
wp_reset_postdata(); 
?>

<?php else:  ?>
   <p><?php _e( 'Sorry, no posts matched your criteria.' ); ?></p>
<?php endif; ?>

I hope this will shed some light on your problem

3
  • Thank you so very, very much for taking the time to write up such a detailed response. I've tried so many options, I think I was ending up with a mess. I am definitely saving what you wrote out as it will help me many times in the future. I copied my code from blog-page.php and moved it to home.php. I changed to just the default query. I then added that function to limit the number of posts. I had it set in Reading Settings, but the page was ignoring that even after moving to home.php. Any idea why that would be? Either way, it's working perfectly now. I can't thank you enough for your help.
    – jphogan
    Commented Jun 10, 2014 at 17:44
  • Did you set a homepage in "Reading Settings >> Front page displays". If not, edit your question and add the code that is currently in home.php so I can quickly have a look at it :) Commented Jun 10, 2014 at 17:57
  • Yeah, I've got that set. See here: imgur.com/n8YINbI Here is my new home.php pastebin.com/bTHRMFqT If I remove the function you gave me, all posts display and there is no pagination. If I add the function, then the correct amount display and it works as it should.
    – jphogan
    Commented Jun 10, 2014 at 20:20
0

I'm late to the party, but none of the above helped me out. I was able to write a little workaround for this totally annoying situation.

  1. Examine the URL
  2. If /page/2 is present, write a redirect rule to add a query string to the url
  3. Make use of that query in your paging.

//Set a URL segments Global (functions.php)
global $segments;
$segments = explode('/', $_SERVER['REQUEST_URI']);
$segments = array_filter($segments);
$segments['classes'] = implode(' ', $segments);

//Add this rewrite in your functions.php to add a query string to target
add_action( 'init', 'forum_paging_redirect', 10 );
function forum_paging_redirect( $redirect_url ) {
    global $segments;

    if($segments[1] === 'forum' && $segments[2] === 'page') {
        echo '<script>window.location = "/forum?topics_page='.$segments[3].'";</script>';
    }
}

// Instead of native pagination function, echo this puppy:
if(!empty($query_topics)) {
    $total = $query_topics->max_num_pages;
    $page = $_GET['topics_page'];

    for($i = 1; $i < $total +1; $i++) {
        if($i == $page) {
            echo '<span aria-current="page" class="page-numbers current">'.$i.'</span>';
        } else {
            echo '<a class="page-numbers" href="/forum/?topics_page='.$i.'">'.$i.'</a>';
        }
    }   
} 

Your Answer

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

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