0

I'm trying a new approach to paginate posts returned in a category.php file. I want to see snippets of 10 posts at a time. Filename is category-xyz.php and this worked before I changed to this method, although I was using showposts=200 and it was returning all 180 posts in that category.

I changed method because several calls I used were deprecated (eg showposts) or not advised. I am using this post's solution for reference:

How to fix pagination for custom loops?

Here's my code:

<?php
// Define custom query parameters
$custom_query_args = array( 
'cat' => 76, 
'posts_per_page' => 5
);

// Get current page and append to custom query parameters array
$custom_query_args['paged'] = get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1;

// Instantiate custom query
$custom_query = new WP_Query( $custom_query_args );

// Pagination fix
$temp_query = $wp_query;
$wp_query   = NULL;
$wp_query   = $custom_query;

        // Output custom query loop rather than use wp_query
        if ( $custom_query->have_posts() ) : 
             while ( $custom_query->have_posts() ) : 
              $custom_query->the_post();
        // Loop output goes here
        ?>
            <div class="pcrmbimgholder">
            <a href="<?php the_permalink() ?>" rel="bookmark"><img src="<?php echo pcrmbimagegrab() ?>" alt="<?php the_title(); ?>" /></a>
            </div>
        <h2><a href="<?php the_permalink() ?>" rel="bookmark"><?php the_title(); ?></a></h2>
        <?php the_content_limit(190, ""); ?>                
                <?php $customField = get_post_custom_values("price"); 
                 if (isset($customField[0])) { 
                 echo "<strong>Price: ".$customField[0];
                 echo "   </strong>";
                } else { 
                ;
                }
                ?>  
                <?php $customField = get_post_custom_values("sku"); 
                 if (isset($customField[0])) { 
                 echo "&#124;   Stock Reference: ".$customField[0] . "&#32;&#32;&#32;";
                } else { 
                ;
                }
                ?>      
        <a class="postbutton" href="<?php the_permalink() ?>" rel="bookmark"><span>View</span></a><div class="separator"></div>     


        <?php

    endwhile;
endif;
// Reset postdata
wp_reset_postdata();

// Custom query loop pagination
previous_posts_link( 'Older Posts' );
next_posts_link( 'Newer Posts', $custom_query->max_num_pages );

// Reset main query object
$wp_query = NULL;
$wp_query = $temp_query;

?>

I have also tried this because I am not sure which parameters I need in the custom query array:

// Define custom query parameters
$custom_query_args = array( 
'cat' => 76, 
'posts_per_page' => 5,
'max_num_pages' => 20,
'paged' => $paged,
);

The pagination link goes to /category/category-name/page/2/ which results in a 404 error. Any ideas why?

5
  • try to enable DEBUG codex.wordpress.org/Debugging_in_WordPress to possibly get error messages
    – Michael
    Nov 24, 2013 at 20:43
  • Thanks. I did this and it said there was an unexpected colon in the code of the custom query loop. I copied and pasted again and it seemed to work. However the pagination link goes to /category/category-name/page/2/ which results in a 404 error. Will update the post.
    – Sara44
    Nov 24, 2013 at 21:27
  • 1
    This: $custom_query->while ( have_posts() ) : should be written as while ( $custom_query->have_posts() ) :. It was wrong in the source Answer too. Nov 24, 2013 at 23:55
  • @CharlesClarkson Thanks Charles, good catch. I did correct this (the linked answer has 2 examples of that code, 1 is correct) and now I'm at the 404 error mentioned above.
    – Sara44
    Nov 25, 2013 at 9:57
  • Thanks for catching that, @CharlesClarkson. Probably one of my best typos of all time. (I fixed the other one, too.) Nov 25, 2013 at 12:23

1 Answer 1

0

The main query runs before the template is loaded, and WordPress decides what template to load based on the results of that query.

You say your default posts_per_page is set to 200, and there are 180 posts in that category, so as far as WordPress knows, there is no page 2. Your custom query that you run in the template with a different posts per page setting is unrelated to the main query.

The solution is to make adjustments to the main query before the template is loaded, via the pre_get_posts action. This would go in your theme's functions.php file:

function category_posts_per_page( $query ) {
    if ( !is_admin()
        && $query->is_category()
        && $query->is_main_query() ) {
        $query->set( 'posts_per_page', 5 );
    }
}
add_action( 'pre_get_posts', 'category_posts_per_page' );

You can then run the normal loop in the template and pagination will work as expected. Also see is_category() in Codex if you want this to apply to a specific single category.

5
  • In the original files I was using 'showposts'. I have changed it to this <?php $recent = new WP_Query("cat=154&posts_per_page=-1"); while($recent->have_posts()) : $recent->the_post();?> but it still doesn't work with the new function you mentioned. Can you explain what you mean by 'normal loop' please?
    – Sara44
    Nov 25, 2013 at 18:52
  • normal loop meaning no custom query, get rid of all your custom query code and just run the plain while( have_posts() ) loop.
    – Milo
    Nov 25, 2013 at 18:58
  • That doesn't seem to work, I still get all posts returned. Should that posts_per_page in functions.php override my posts_per_page=-1 in the category template file?
    – Sara44
    Nov 25, 2013 at 19:49
  • if you've removed the custom query from your template, there should be no query arguments there at all. your template should just be the default, plain, unedited category template.
    – Milo
    Nov 25, 2013 at 20:03
  • That works a treat thanks, removed all query calls like you said.
    – Sara44
    Nov 25, 2013 at 21:41

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.