Show a different number of posts per page depending on context (e.g., homepage, search, archive)

In the Reading Settings, there is place to set the number of posts shown that affects the number of posts shown in all contexts. I’d like to show instead a certain number of posts on the homepage, and a different number of posts on pages like archive, search results, etc.

reading-settings-blog-pages-show-at-most-per-page

Read More

I realize I could do this by editing the theme files and changing the query parameters there, but I’d prefer to have easier access to a simple settings page. A long time ago, I came across a plugin that did this, but I can’t locate it now.

Does anyone know of a plugin to do this, or even a function I could put in functions.php to accomplish the same thing?

Related posts

Leave a Reply

4 comments

  1. I believe the best way to do this in a plugin is to run the following sample function when the pre_get_posts action hook is encountered. The $wp_query object is available, meaning your conditional tags are available, but before WordPress gets the posts, which means you are changing query vars prior to the first query being run, rather than adding a second query like when query_posts() is used in a theme file.

    function custom_posts_per_page($query) {
        if (is_home()) {
            $query->set('posts_per_page', 8);
        }
        if (is_search()) {
            $query->set('posts_per_page', -1);
        }
        if (is_archive()) {
            $query->set('posts_per_page', 25);
        } //endif
    } //function
    
    //this adds the function above to the 'pre_get_posts' action     
    add_action('pre_get_posts', 'custom_posts_per_page');
    
  2. you could do a custom loop using query_posts, and specify the number of posts by is_home, is_archive, etc.

    just a simple if statement along with query_posts

  3. To adding to this question. Does somebody know how to determine post_per_page for this function function custom_posts_per_page($query) if add the new page to index.php like this:

    <?php
    if ($_GET['new'] == 1) 
    {
        include ( TEMPLATEPATH . '/newpage.php' );
        exit;
    }
    ?>
    
  4. I realize I could do this by editing the theme files and changing the query parameters there, but I’d prefer to have easier access to a simple settings page.

    In the interest of completeness, I found that query_posts combined with $query_string concatenation works well.

    I placed this code in index.php (my theme doesn’t have category.php) …

    <?php 
    if (!is_front_page()) { 
        query_posts($query_string . "&posts_per_page=20"); 
    }
    ?>
    

    Of course what we’re doing here is modifying the internal query string of the loop, overriding the default number of posts per page.

    It works a treat for providing a smaller list of posts on the homepage where I am showing full posts, and a much larger list of posts everywhere else (categories, by date, etc) where I am only showing post summaries.

    However, please do note that unlike the accepted answer, this will run the query twice, so it is not as nice a solution.