I have thousands of posts that I am displaying on my home page. I want to control number of posts so for this I am using posts_per_pagebut it is not working for me. All other arguments works but posts_per_page is not working. I have pagination on this page and posts_per_page works for all other pages of pagination but not for first (main) page. So for testing purpose i create a blank template that just have one simple WordPress loop and not have pagination or any thing else that is displaying just post title and in this template i have limit on number of posts again but posts_per_page is not working even on this page. I have tried disabling all plugins but there was no effect so i think this issue is with theme that is setting posts_per_page value dynamically. I am also resetting the query before this loop using wp_reset_query(); and tried this code in functions.php as well.

add_action( 'pre_get_posts',  'set_posts_per_page'  );
function set_posts_per_page( $query ) {
    global $wp_the_query;
    $query->set( 'posts_per_page', 12 );
    return $query;

But nothing working for me. I have tried to display query content using var_dump($query->request)and in the query limit was 12 but on page i am still seeing 100+ posts. On WordPress settings page on theme settings page the posts limit is 12 but on front end this limit is not working. Here is the result of this query.

string(489) "SELECT SQL_CALC_FOUND_ROWS wp_mdw75t47kk_posts.ID FROM wp_mdw75t47kk_posts INNER JOIN wp_mdw75t47kk_postmeta ON ( wp_mdw75t47kk_posts.ID = wp_mdw75t47kk_postmeta.post_id ) WHERE 1=1 AND ( wp_mdw75t47kk_postmeta.meta_key = '_imwb_zonpress_post_ctr' ) AND wp_mdw75t47kk_posts.post_type = 'post' AND (wp_mdw75t47kk_posts.post_status = 'publish' OR wp_mdw75t47kk_posts.post_status = 'private') GROUP BY wp_mdw75t47kk_posts.ID ORDER BY wp_mdw75t47kk_postmeta.meta_value+0 DESC LIMIT 0, 12" 

I am also sharing url of this testing page if anybody wants to see this. Test Page link You will also be able to see this issue on main page as well. For me this is very strange issue because i have tried everything from google but nothing working for me.
I am using covert store builder theme. Any suggestion will be much appreciated. Thank you!

Here is complete code for this loop.

$args = Array(
        'posts_per_page' => 12

$query = new WP_Query( $args );

<?php while ( $query->have_posts() ) : $query->the_post(); ?> 

Then there is some code to display image, title and excerpt and I think this should not effect number of posts. After this these lines are given

endwhile; ?>

But as i mention i have tried this code in a blank template without pagination but still posts_per_page was not working. So i think an external hook setting this value. I have tried to find out this in theme files but was not successful. I know this is just because of this theme.

  • 1
    How are the posts loaded on the homepage? – Jacob Peattie Mar 15 '18 at 0:00
  • Jobs are loading with simple WordPress loop which is working perfectly and everything else in loop arguments as well but posts_per_page is not working. – wplearner Mar 15 '18 at 1:33
  • 1
    Yes I can add that. But i have tried this even without pagination in a custom template but still number of posts was 100 plus. – wplearner Mar 16 '18 at 19:18
  • 1
    have you tried suppress_filters in your query or removing all filters from pre_get_posts? – Alex Sancho Mar 16 '18 at 20:51
  • 1
    @Awan Please edit your question, and move all crucial information from the comments to the question text, so we can clean up this overly long comment thread. :) – fuxia Mar 17 '18 at 17:42

Did you try this one?

    $blogpost  =  new WP_Query(array(         
       'post_type'      => 'post',
       'posts_per_page' => 6
<?php while($blogpost->have_posts()) : $blogpost->the_post(); ?>
// Writhe your Blog article Here.
<?php endwhile; ?>
  • That is useful for me to change default posts_per_page in search.php while loop to display more excerpts in search results layout. But pagination is broken. TwentySeventeen (child) theme – dstonek Mar 2 at 15:07

Did you try this one?

function posts_on_homepage( $query ) {
    if ( $query->is_home() && $query->is_main_query() ) {
        $query->set( 'posts_per_page', 10 );
add_action( 'pre_get_posts', 'posts_on_homepage' );
  • Tried this but not working – wplearner Mar 14 '18 at 17:16

Have you tried adding the following before the main args and the loop?

<!-- Modify pagination function for front page -->
global $paged, $wp_query, $wp;
$args = wp_parse_args($wp->matched_query);
if ( !empty ( $args['paged'] ) && 0 == $paged ) {
$wp_query->set('paged', $args['paged']);
$paged = $args['paged']; } ?>

Then add the pagination like so:

$args = array(
'posts_per_page' => 12,
'paged' => $paged ); ?>

$query = new WP_Query($args);

<?php if ($query->have_posts()) : $i = 1; ?>

<?php while ( $query->have_posts() ) : $query->the_post(); ?>

// Content Here

<?php $i++; endwhile; ?>
<?php else : ?>
<h2>Content not found!</h2>
<?php endif; ?>

//pagination code

In my case I am using WP pagenavi, so I would use:

<?php wp_pagenavi( array( 'query' => $query )); ?>
<?php wp_reset_query(); ?>

Try adding this one before the query argument.

    if (get_query_var('paged')) {
        $paged = get_query_var('paged');
    } elseif (get_query_var('page')) {
        $paged = get_query_var('page');
    } else {
        $paged = 1;

At the argument, make 'paged' => $paged


I suspect that your theme is binding to a filter that is resetting the query also within your loop, which is causing unending recursion. If that is the case, you have three options:

You can ditch the theme and use another one. That is probably a bad answer if you are heavily invested in it.

You can hack the theme, which is also a bad answer, because you'll have to do it again when it updates, or you'll have to override a bunch of its core code in a child theme which can get very messy.

Or, you can do it the quick and dirty way, which is to just use a good old for loop instead of while.

$GLOBALS['my_counter'] = 12;
$args = Array(
    'posts_per_page' => $GLOBALS['my_counter'];

$query = new WP_Query( $args );

for ( $i = 0; $i < $GLOBALS['my_counter'], $i++ )
    if (!$query->the_post())

It's ugly, but it should do what you want. The for loop will only run 12 times, regardless of whether or not anything else is resetting the query. If you see duplicate posts, you can also put a break point in the loop and use debug_backtrace(1) to sniff out where it is happening, which is not really feasible in a while loop, unless you like the idea of about 8 bjillionty pages of debug code and possibly crashing your server.

If this does work for you, consider finding a more elegant solution for a couple of reasons:

A) Globals are bad.

B) Doing things the wrong way usually leads to more doing things the wrong way. I can't say what is the right way for your specific theme, but if it provides any way to do what you want on your home page, you should do that. If it does not provide any kind of api though, do what you have to.

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.