I am designing a theme where the home page (i.e. is_home()) should only display the latest blog post. I want to do something like $wp_query->update_option('posts_per_page', 1) every time I am on the home page. All other pages that display posts (like archives) should just follow the user defined option.

This seems a bit unnecessary to do every single time since the option should just be set once, right? Is it possible within The Loop to just ignore the user-set option of posts_per_page and force have_posts() to just be set to one post?

In general, where should this kind of "set-it-once" stuff go? I don't really think it should be a plug-in because it is theme specific. I also don't want to mess with the user's options which is why update_option isn't the best choice for this problem.

3 Answers 3


Alternate approach (if you want/need to keep this in functions.php and go via hooks instead of modifying template) would be something like this:

add_action( 'pre_get_posts', 'pre_get_posts_home' );

function pre_get_posts_home( $query ) {

    global $wp_query;

    if( $wp_query == $query && $query->is_home )
        $query->set( 'posts_per_page', 1 );
  • Where can I find a canonical list of filter/action hooks? (adambrown.info/p/wp_hooks) doesn't list pre_get_posts, nor does the Codex mention it on (codex.wordpress.org/Plugin_API/Filter_Reference). Jun 4, 2011 at 0:39
  • I did a little more research and noticed that on the Codex, pre_get_posts (I thought it was a filter so I looked for it as a filter) is identified as an action. Is there a difference in the above code between calling add_filter vs add_action? The difference in semantics on the Codex isn't quite clear to me. Jun 4, 2011 at 0:50
  • @Avry ah, sorry, should be add_action() indeed :) The difference is that filter expects and uses returned value, action does not. But technically add_filter() and add_action() are identical (in fact one of those just calls another) and distinction is for human convenience, not code. Edited snippet.
    – Rarst
    Jun 4, 2011 at 9:22

posts_per_page should be set once the at settings reading panel, and acts as a general option unless defined else using query_posts() for example if you want your homepage to display only one then the place this code above your loop:

if (is_home()){ // conditional check for homepage
    global $query_string;
    parse_str( $query_string, $args );
    $args['posts_per_page'] = 1;
    query_posts( $args );
  • I think you meant $args['posts_per_page'] = 1; ? :)
    – Rarst
    Jun 3, 2011 at 18:36
  • Where should this code snippet go? In loop.php? Jun 3, 2011 at 23:33
  • like i posted in my answer, just above the loop
    – Bainternet
    Jun 3, 2011 at 23:40

I prefer use a function than use global variable, like this:

if (is_home()) set_query_var('posts_per_page', 1);

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.