Different number of posts in each category

I have categories driven site. I have different template for each category. I would like to set different number of posts – different for each category. Plus I would like to add proper previous and next links in each category.

for example in this category-1.php I want 4 posts per page:

Read More
<?php query_posts('showposts=4'); ?>
<a href="<?=next_posts()?>"> PREVIOUS </a>
<a href="<?=previous_posts()?>"> NEXT </a>
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
...
<?php endwhile; endif; ?>

but in this example next_posts() and previous_posts() doesn’t work.

Related posts

Leave a Reply

5 comments

  1. As @StephenHarris pointed out there’s also the pre_get_posts filter.

    function hwl_home_pagesize( $query ) 
    {
        if ( is_category( 9 ) ) 
        {
            // If you want "posts per page"
            $query->query_vars['posts_per_page'] = 1;
            return;
        }
        if ( is_category( 'movie' ) )
        {
            // If you want "showposts"
            $query->query_vars['showposts'] = 50;
            return;
        }
    }
    add_action( 'pre_get_posts', 'hwl_home_pagesize', 1 );
    

    Example altered from Codex example.

  2. You can use the pre_get_posts hook (conditionals are available):

    function wpse47875_change_posts_per_page( $query ) {
        //Only alter main query. This only works for 3.3+
        if( ! $query->is_main_query() )
            return;
    
        if ( is_category('9') ){
            //Display 4 posts for category 1
            $query->set( 'posts_per_page', 4);
        }
    }
    add_action('pre_get_posts', 'wpse47875_change_posts_per_page', 1);
    

    You probably only want to change the ‘main query’, so the first check is important. If you are using WP < 3.3 then you can check instead:

     if( $wp_the_query === $query ){
        //$query is the main query
     }else{
        //$query is *not* the main query
     }
    
  3. Parse Request Action

    Not shure if this will work – it may be that the conditionals are not working at this point…

    // inside functions.php
    function wpse47861_intercept_main_query( $wp )
    {
        // default
        $nr_posts = 10; 
    
        if ( is_category( 'CAT NAME' ) )
            $nr_posts = 4;
    
        if ( is_category( array( 9 /*Ex. Cat-ID*/, 'CAT NAME A', 'CAT NAME B' ) ) )
            $nr_posts = 6;
    
        // Modify the main query object
        $wp->query_vars['showposts'] = $nr_posts;
    
        return $wp;
    }
    add_filter( 'parse_request', 'wpse47861_intercept_main_query' );
    

    Posts Limit filter

    This would be the other chance, as maybe conditionals are already available there.

    function wpse47861_intercept_query_limit( $limit )
    {
        // default
        $nr_posts = 10; 
    
        if ( is_category( 'CAT NAME' ) )
            $nr_posts = 4;
    
        if ( is_category( array( 9 /*Ex. Cat-ID*/, 'CAT NAME A', 'CAT NAME B' ) ) )
            $nr_posts = 6;
    
        return "LIMIT 0, {$nr_posts}";
    }
    add_filter( 'posts_limit', 'wpse47861_intercept_query_limit', 9999 );
    

    Note: Both functions are not tested. Plus: Use one or the other. Both should be placed in your functions.php file.

  4. With query_posts, pagination won’t work correctly, unless you use query_posts() in a page template and you set the ‘paged’ query var appropriately: http://codex.wordpress.org/Template_Tags/query_posts

    But it may be easier to use a plugin called Custom Post Limits and leave your category page loops the same. You can set different first page and paged limits for each category. See WordPress › Custom Post Limits « WordPress Plugins

  5. I have flexible way where is possible to set any per_page value for each/any woprdpress site page:

    • open functions.php of the current wp theme

    • use smth like next:

    *

    add_filter('pre_option_posts_per_page', function($num)
    {
        if ($_SERVER['SCRIPT_URL'] == '/category/faq/')
        {
        return 999;
        }
    
        return $num;
    });