0

Can anyone figure out why viewing pages in my child categories results in a 404, when the same $paged code works fine for my index file? This is inside of my category-15.php (it's to affect all child categories under parent category ID 15).

  <?php
    $PostNum = 1;
    $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
    $args = array(
        'cat' => $cat,
        'posts_per_page' => 2,
        'orderby' => 'date',
        'order' => 'ASC',
        'paged' => $paged,
    );
    $CustomQueryIdentifier = new WP_Query($args);
  ?>

    <h1><a href="<?php the_permalink(); ?>"><?php the_category(' '); ?></a></h1>

    <?php
      if ( $CustomQueryIdentifier->have_posts() ) : while ( $CustomQueryIdentifier->have_posts() ) : $CustomQueryIdentifier->the_post();
    ?>
    <div class="container">
      <p class="number"><a href="<?php the_permalink(); ?>"><?php $postnumber = $CustomQueryIdentifier->current_post; echo $postnumber+1 ?></a></p>
      <?php the_content(''); ?>
    </div>

  <?php endwhile; endif; ?>

  <div class="navigation">
    <?php next_posts_link('&laquo; Older Entries', $CustomQueryIdentifier->max_num_pages) ?>
    <?php previous_posts_link('Newer Entries &raquo;') ?>
  </div>

  <?php wp_reset_postdata(); ?>
2
  • How many posts are in the category you are viewing, and what is the posts per page value in the reading settings page? If you are trying to view a page beyond the number of posts you have, you get a 404.
    – Milo
    Commented Jul 8, 2014 at 15:13
  • @Milo The category has 3 posts. Viewing the first page shows only 2 posts (as expected). The reading settings has 5 posts per page, and the query above is 2.
    – Arkuen
    Commented Jul 9, 2014 at 0:15

1 Answer 1

1

There are a lot of questions here regarding pagination, it is definitely one of the least understood aspects of how WordPress works internally.

To understand why you get 404s, we'll start by looking at the Action Reference in Codex to see the process WordPress follows for each request.

The process begins by loading up the plugins and theme, and doing some initialization to set everything up, etc., etc.. The part we are interested in begins at parse_request, when WordPress determines what sort of page is being requested, and parse_query, when the query variables are set to generate the Main Query.

The next action is pre_get_posts, which gives us an opportunity to modify the main query. This is where you want to execute your own code to change the main query, for example, setting a different posts_per_page value (hint, hint).

Then we reach the wp action, after the main query is run, and finally the important bit of info in this explanation- the template_redirect action. This is the action where WordPress determines what template to load, based on the results of the main query. If it's a category, the category template is loaded, if it's an archive, the archive template is loaded, and if it's a 404- the 404 template is loaded.

Yes, bold text means that last part was important, and hopefully we are beginning to understand the problem. WordPress decided the request is a 404 before your template was ever loaded. Whatever the results you get by running queries in the template are irrelevant. If the main query doesn't return post(s), it's a 404.

In your case, you're getting a 404 because the main query is loading 5 posts per page, and you only have 3, there is no second page as far as the main query is concerned.

( But wait a minute, you say, why does it work on some pages and not others? Yes, confusingly enough it won't always result in a 404, for example when the request is a singular page. )

The solution to your category problem was hinted at earlier in the story- if you want to modify the query, use pre_get_posts before the main query is run.

// modify main query for category ID 15 and all its children
function wpd_category_query( $query ) {
    if( $query->is_main_query() && $query->is_category() ) {
        $parent = 15; // your parent category
        $categories = get_term_children( $parent, 'category' );
        $categories[] = $parent;

        if( is_category( $categories ) ) {
            $query->set( 'posts_per_page', 2 );
        }
    }
}
add_action( 'pre_get_posts', 'wpd_category_query' );
2
  • Thanks for the fantastic writeup! I understand the problem quite a bit better because of it. I plugged in your code and now it's no longer returning a 404, but instead it's returning the same posts in page 2 (Only ever shows posts 1-2 and doesn't swap to post 3).
    – Arkuen
    Commented Jul 9, 2014 at 10:42
  • that shouldn't be the case, there must be something else modifying the query. make sure there's nothing overwriting $wp_query in the template- no calls to query_posts. try an unedited template file and disable plugins to test. there may also be something else in functions.php changing the query.
    – Milo
    Commented Jul 10, 2014 at 15:43

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.