Skip to main content
replaced http://wordpress.stackexchange.com/ with https://wordpress.stackexchange.com/
Source Link

I just noticed your comment that you wanted to accomplish this via a filter, so here you go (this basically expounds on the comments I've made on your original question and @DavidLee's answer@DavidLee's answer).

I just noticed your comment that you wanted to accomplish this via a filter, so here you go (this basically expounds on the comments I've made on your original question and @DavidLee's answer).

I just noticed your comment that you wanted to accomplish this via a filter, so here you go (this basically expounds on the comments I've made on your original question and @DavidLee's answer).

added 627 characters in body
Source Link

Edit: Additional answer

OK, try this:

add_filter ('pre_get_posts', 'set_posts_per_page_on_front_end_main_query') ;
add_filter ('the_posts', 'respect_posts_per_page') ;

function
respect_posts_per_page ($posts, $wp_query)
{
    return (array_slice ($posts, 0, $wp_query->get ('posts_per_page', count ($posts)))) ;
}

function
set_posts_per_page_on_front_end_main_query ($wp_query)
{
    if ( is_admin () || !$wp_query->is_main_query ()) {
        return ($wp_query) ;
        }

    $wp_query->set ('posts_per_page', 1) ;

    return ($wp_query) ;
}

Edit: Additional answer

OK, try this:

add_filter ('pre_get_posts', 'set_posts_per_page_on_front_end_main_query') ;
add_filter ('the_posts', 'respect_posts_per_page') ;

function
respect_posts_per_page ($posts, $wp_query)
{
    return (array_slice ($posts, 0, $wp_query->get ('posts_per_page', count ($posts)))) ;
}

function
set_posts_per_page_on_front_end_main_query ($wp_query)
{
    if ( is_admin () || !$wp_query->is_main_query ()) {
        return ($wp_query) ;
        }

    $wp_query->set ('posts_per_page', 1) ;

    return ($wp_query) ;
}
Source Link

I just noticed your comment that you wanted to accomplish this via a filter, so here you go (this basically expounds on the comments I've made on your original question and @DavidLee's answer).

The following will result in 1 and only 1 post, regardless of stickies. If the most recently published post is sticky, you will get it. If the most recently published post is not sticky, you will still get it. And, you will get no other posts, sticky or otherwise.

add_filter ('pre_get_posts', 'get_only_one_post') ;

function
get_only_one_post ($wp_query)
{
    if (is_admin () || !$wp_query->is_main_query ()) {
        // we're not in the Main Loop, so return the query unmodified
        return ($wp_query) ;
        }

    // order by most recently published 1st
    // this isn't really necesary (since it is the default),
    // but include it just in case some other filter has modified that default
    $wp_query->set ('orderby', 'date') ;
    $wp_query->set ('order', 'DESC') ;

    // limit to 1 post, not counting stickies
    $wp_query->set ('posts_per_page', 1) ;
        
    // disable the special processing of sticky posts.
    // without this, ALL sticky posts will be returned, whether they match
    // the rest of the query_vars or not
    $wp_query->set ('ignore_sticky_posts', true) ;

    return ($wp_query) ;
}

Explanation

Without 'ignore_sticky_posts' => true

The following is done:

  1. retrieve posts according to query vars, including respecting posts_per_page and orderby
    • any sticky posts that match query vars will already be included in the results
  2. move sticky posts that are included in the results to the front of the list
  3. retreive all sticky posts
    1. those not already in the results are preprend to the list

With 'ignore_sticky_posts' => true

The following is done:

  1. retrieve posts according to query vars, including respecting posts_per_page and orderby
    • any sticky posts that match query vars will already be included in the results