Objective: When a category is clicked I would like the category.php page to dynamically pull in all posts filed under that clicked category.

Example: News -> (Action:Click) -> Category = News

Currently my loop is pulling in 3 posts from the Category:Uncategorized no matter what category is clicked. I checked my loop and arguments and it appears that everything should be working as intended. I would appreciate any fresh eyes on this.


<?php get_header(); ?>
<section class="component" role="main">
<header class="header">
<h1 class="entry-title"><?php single_cat_title(); ?></h1>
<?php if ( '' != category_description() ) echo apply_filters( 'archive_meta', '<div class="archive-meta">' . category_description() . '</div>' ); ?>
<section class="component responsive">
$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;

// Grabs the selected category
foreach((get_the_category()) as $category)
    $postcat= $category->cat_ID;

$args = array(
           'posts_per_page' => 7,
           'paged' => $paged,
           'cat' => $postcat // Passes the selected category to the arguments

$custom_query = new WP_Query( $args );
$post_number = 0;

if ( $custom_query->have_posts() ) : while($custom_query->have_posts()) : $custom_query->the_post(); ?>
        <?php the_title(); ?>
    <?php endwhile; else : ?>
<?php endif; ?>
    <div class="clear"></div>
    <?php if (function_exists("pagination")) {
    } ?>
  • I'm not sure I understand, category.php is for category archives, so it should already do what you wanted out of the box, yet you're replacing the query with a brand new one and throwing away all the work WP did, it doesn't make a lot of sense. If I had to guess, you wanted to change the template so it only showed 7 posts per page, but rather than modifying the main query via pre_get_posts you put a new query in, and now the new query doesn't do all the things the original one did and you're trying to figure out how to duplicate the work it did? – Tom J Nowell Oct 9 '18 at 13:59

Your entire template is broken because rather than modifying the main query, you threw it away and put a brand new query in:

$args = array(
           'posts_per_page' => 7,
           'paged' => $paged,
           'cat' => $postcat // Passes the selected category to the arguments

$custom_query = new WP_Query( $args );

WP did a lot of work figuring out which page, how many posts, what kind of posts etc, which you have to duplicate in the new query. Again, this is a brand new query that only does what you tell it to do. It's also very bad for performance/speed and leads to slower pages.

Instead, if we use the pre_get_posts filter to limit the archive to 7 posts as you originally intended, all the pagination code can be removed, as can the custom query:

First, lets adjust the query to only show 7 posts in functions.php if the main query is for a category archive:

function limit_category( $query ) {
    if ( $query->is_category() && $query->is_archive() && $query->is_main_query() ) {
        $query->set( 'posts_per_page', '7' );
add_action( 'pre_get_posts', 'limit_category' );

Now we can use standard pagination functions, and a normal, standard posts loop in category.php, e.g.

if ( have_posts() ) { // if we have posts
    while( have_posts() ) { // while we still have posts
        the_post(); // set the current post
        the_title(); // display its title
        the_content(); // display its content
    // display the pagination links
    <div class="nav-previous alignleft"><?php previous_posts_link( 'Older posts' ); ?> </div>
    <div class="nav-next alignright"><?php next_posts_link( 'Newer posts' ); ?></div>
} else {
    echo "<p>No posts found</p>";
  • I appreciate your feedback. The reason I ditched the standard WP loop was because I originally wanted 7 posts to display on the first page and 9 on the subsequent pages with numbered pagination instead of the standard Previous/Next links. After that didn't work I decided on 7 per page so I could keep the numbered pagination. I don't think I can use this solution unless it allows for numeric pagination. – Peter Oct 9 '18 at 14:13
  • To put 9 on the second page you'd need to adjust the query parameters based on the current page, but that's exactly what the pre_get_posts filter is for, it lets you change the parameters before WP goes and fetches the posts. However, you made no mention of any kind of the numeric pagination in your original question. Perhaps you should have asked how to implement your original problem of 7 on the first and 9 on subsequent pages? Note that you will never be able to use the WP pagination link functions if your pages have differing post counts, but you should never just replace the main query – Tom J Nowell Oct 9 '18 at 14:23
  • Thank you for the note. I'll try and implement your solution and let you know what happens. – Peter Oct 9 '18 at 14:50
  • 1
    This solved my issue. Thank you for your explanations and examples. Takeaway, don't modify the default WP Query unless absolutely necessary. I am selecting this as the answer. Thanks again. – Peter Oct 9 '18 at 15:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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