1

I have a WP_Query which has the "posts_per_page" parameter set to 12. I am then using a while loop to iterate over all of the posts and an IF statement to check whether a condition is true or false. I would like to be able to display 12 posts which return true however, the loop is obviously also counting each post returning false and displaying nothing. For example, 5 posts would be displayed but the other 7 are not displayed.

$args = array(
   'post_type'         => $post_slug,
   'posts_per_page'    => 12,
   'paged'             => 1,
   'post_status'       => 'publish',
);

 $topicsHub = new WP_Query($args);

 <?php while ( $topicsHub->have_posts() ) : $topicsHub->the_post();
           
   $resource_type = get_post_type();

   if($resource_type == 'tools') {
      $stream = get_field('stream_name', get_the_ID());
                    
      $tooltype = get_field('tools_type', get_the_ID());
      $stream_name = $stream;
      foreach ($options['streams'] as $key => $subscription) {
        if(in_array($subscription['parent_stream_name'], $stream)){
          $stream_name = [];
          $stream_name[] = $subscription['name'];
            break;
        }
      }
      // Custom function             
      if(check_if_user_has_access($stream_name, 'something')) {
        if($tooltype == 'free') {
          continue;
        }  
      } else {
         if($tooltype == 'premium') {
            continue;
         }
      }
   }
   ?>
   <div class="u-12 u-6@sm u-4@md resource__main-tab--item">

      <?php get_template_part('partial/content', 'topics-card'); ?>

   </div>

<?php endwhile; ?>

I understand why this is happening but am not sure how I could only show 12 posts that only return true.

2 Answers 2

1

The simplest solution would be to query all posts using a -1 in place of the 12 in your 'posts_per_page' argument of your query. Then use a counter that ticks up if all of the above conditions equal true.

$args = array(
   'post_type'         => $post_slug,
   'posts_per_page'    => -1,
   'paged'             => 1,
   'post_status'       => 'publish',
);

 $topicsHub = new WP_Query($args);
 $post_counter = 0;

 <?php while ( $topicsHub->have_posts() ) : $topicsHub->the_post();
   // if the $post_counter variable gets above your limit, break from the loop
   if ($post_counter >= 12) { break; } 
           
   // conditional statements, breaks and continues...
   ?>
   <div class="u-12 u-6@sm u-4@md resource__main-tab--item">

      <?php get_template_part('partial/content', 'topics-card'); ?>

   </div>

<?php 
// increment $post_counter every time the loop gets this far (the above div will have printed)
$post_counter++;
endwhile; ?>

However, if you wanted to query only the first 12 posts that matched your conditions, take a look at advanced query parameters for WP_Query($args). There are tons of IFs, ORs, XORs, etc. that you can use inside of the $args variable. Just might get super messy and unreadable with the amount of logic you're using in your while statement, so I'd recommend using the first method.

1

I ran into a similar issue myself recently. I was trying to modify the search results with specific criteria being met. What I eventually did is modify the Query itself rather than trying to do that after the fact.

I am not sure what your custom function does so I can't say for sure if this would work for you but here's how I would alter the query using metadata before displaying it. See this doc (I am assuming the get_field function is coming from acf and you can do this with acf fields) :

$args = array(
   'post_type'         => $post_slug,
   'posts_per_page'    => 12,
   'paged'             => 1,
   'post_status'       => 'publish',
   'meta_query' => array(

        array(
            'key'     => 'tooltype',
            'value'   => array( 'free', 'premium')
            'compare' => 'LIKE',
        ),
        array(
            'key' => 'stream_name',
            'value'   => array( 'something'),
            'compare' => 'LIKE',
        ),
    ),
);

Then you would only get posts that match that criterion rather than doing it after the fact.

I can also see that it's possible your code might be trying to limit what is available based on user meta. So another approach would be to alter the output template file (topics-card) instead and add a disabled attribute that disables the link to the posts or alter the HTML so that the post is not a link that doesn't match the criteria for access using the same functions your are using now. That way you don't have to mess with pagination or the query at all.

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.