1

I'm writing a custom post plugin which is displaying the custom posts in groups as tabs. For each group 4 post. Is it possible to write a query with offset which will increase with every loop? So the result would be:
- first query displays posts from 1 to 4
- second query displays posts from 5 to 8
- third query displays post from 9 to 12 etc.

        <div class="official-matters-tabs">
          <?php $args = array('post_type' => 'official-matters', 'showposts' => 4, 'orderby' => 'date', 'order' => 'ASC',); $the_query = new WP_Query( $args ); ?>
          <?php while ( $the_query->have_posts() ) : $the_query->the_post(); ?>
          <div class="info-tab col-xl-3">
            <div class="info-img">
              <?php the_post_thumbnail(); ?>
            </div><!-- .info_img -->
            <a data-toggle="collapse" href="#collapse-<?php the_ID(); ?>" class="info-title" role="button" aria-expanded="false" aria-controls="collapse-<?php the_ID(); ?>">
              <?php the_title(); ?>
            </a>
          </div><!-- .info-tab -->
        <?php endwhile;?>
        <?php wp_reset_postdata(); ?>
        </div><!-- .official-matters-tabs -->

        <div class="official-matters-content">
          <?php $args = array('post_type' => 'official-matters', 'showposts' => 4, 'orderby' => 'date', 'order' => 'ASC',); $the_query = new WP_Query( $args ); ?>
          <?php while ( $the_query->have_posts() ) : $the_query->the_post(); ?>
          <div class="info-tab-content collapse" id="collapse-<?php the_ID(); ?>">
            <div class="card card-body">
                <?php the_excerpt(); ?>
            </div><!-- .card -->
          </div><!-- .info-tab-content -->
        <?php endwhile;?>
        <?php wp_reset_postdata(); ?>
        </div><!-- .official-matters-content -->

      </div><!-- .official-matters-group -->
  </div><!-- #collapse-official-matters -->

UPDATED

I made the changes that you suggested. My biggest problem right now with the query is the output that I'm getting:

<div class="official-matters-group">
 <div class="official-matters-tabs">
  <div class="info-tab col-xl-3">
    ...
  </div>
</div>
<div class="official-matters-content">
 <div class="info-tab-content collapse">
  ...
 </div>
 <div class="official-matters-tabs">
   <div class="info-tab col-xl-3">
   ...
   </div>
</div>
<div class="official-matters-content">
   <div class="info-tab-content collapse">
   ...
   </div>
   <div class="official-matters-tabs">
      <div class="info-tab col-xl-3">
      ...
      </div>
   </div>
</div>

and what I need is:

<div class="official-matters-group">
 <div class="official-matters-tabs">
  <div class="info-tab col-xl-3">
   ...
  </div>
  <div class="info-tab col-xl-3">
   ...
  </div>
  <div class="info-tab col-xl-3">
   ...
  </div>
  <div class="info-tab col-xl-3">
   ...
  </div>
 </div>
 <div class="official-matters-content">
  <div class="info-tab-content collapse">
   ...
  </div>
  <div class="info-tab-content collapse">
   ...
  </div>
  <div class="info-tab-content collapse">
   ...
  </div>
  <div class="info-tab-content collapse">
   ...
  </div>
</div> 

I need the 4 post grouped in official-matters-group and looped this as many times until all post are shown. And I don't have an idea how to get it done.

so now my query code looks like this:

        <?php global $duplicated_posts;
          $args = [
              'post_type' => 'official-matters',
              'showposts' => 20,
              'orderby' => 'date',
              'order' => 'ASC',
              'post__not_in' => $duplicated_posts
          ];
          $query = new \WP_Query($args); ?>

          <div class="official-matters-group">
            <?php if( $query->have_posts() ) : ?>
              <?php while( $query->have_posts() ) : $query->the_post();
                    $duplicated_posts[] = get_the_ID();
              ?>
                <div class="official-matters-tabs">
                  <div class="info-tab col-xl-3">
                    <div class="info-img">
                      <?php the_post_thumbnail(); ?>
                    </div><!-- .news_img -->
                    <a data-toggle="collapse" href="#collapse-<?php the_ID(); ?>" class="info-title" role="button" aria-expanded="false" aria-controls="collapse-<?php the_ID(); ?>">
                      <?php the_title(); ?>
                    </a>
                  </div>
                </div><!-- .official-matters-tabs -->

                <div class="official-matters-content">
                  <div class="info-tab-content collapse" id="collapse-<?php the_ID(); ?>">
                    <div class="card card-body">
                        <?php the_content(); ?>
                    </div><!-- .card -->
                  </div><!-- .info-tab-content -->
                 </div><!-- .offical-matters-content -->
                <?php
                endwhile;
                wp_reset_postdata();
              endif;
            ?>
        </div><!-- .official-matters-group -->
    </div><!-- .collapse-official-matters -->

UPDATED

So far I got to this point:

<div id="collapse-official-matters" class="col-xl-12">
   <div class="official-matters-group">

     <?php
      $args = array(
        'post_type' => 'sprawy-urzedowe',
        'showposts' => 20,
        'orderby' => 'date',
        'order' => 'ASC',
        'post__not_in' => $duplicated_posts
     );

     $the_query = new WP_Query($args);
     if ($the_query->have_posts()) :
       $counter = 0;
       while ($the_query->have_posts()) : $the_query->the_post();
           if ($counter % 4 == 0) :
               echo $counter > 0 ? '</div>' : '';
               echo '<div class="official-matters-tabs">';
           endif;
           ?>

           <div class="info-tab col-xl-3">
             <div class="info-img">
               <?php the_post_thumbnail(); ?>
             </div><!-- .news_img -->
             <a data-toggle="collapse" href="#collapse-<?php the_ID(); ?>" class="info-title" role="button" aria-expanded="false" aria-controls="collapse-<?php the_ID(); ?>">
               <?php the_title(); ?>
             </a><!-- .info-title -->
           </div><!-- .info-tab -->

     <?php
       $counter++;

       endwhile;
       endif;
       wp_reset_postdata();
     ?>
   </div>


   </div><!-- .official-matters-group -->
</div><!-- .collapse-official-matters -->

but I don't know how to add the code below to get the output that I need

<div class="official-matters-content">
  <div class="info-tab-content collapse" id="collapse-<?php the_ID(); ?>">
    <div class="card card-body">
        <?php the_content(); ?>
    </div><!-- .card -->
  </div><!-- .info-tab-content -->
</div>
  • 1
    Don't run so many separate queries. Just run one big query, then add a counter variable. Before the while loop begins, set the counter to 1. Then inside your while loop, have if/elseif - if($counter==1) or you could get fancy and use modulus if($counter%4==0) for multiples of 4, etc. Set your differing output inside each if/elseif. Then at the end just before endwhile increment the counter, so next time it loops through it will be set to the next number. – WebElaine May 9 '18 at 21:45
  • hmm I don't think there's a need for a separate query for each tab at all, I agree with @WebElaine – Tom J Nowell May 9 '18 at 22:51
  • is it correct to have two while in one query? because when there is only one while, my code comes out mixed up like in some .official-matters-content i get .info-tab col-xl-3 which should be only in .official-matters-tabs. – Dariusz May 10 '18 at 7:01
  • No, you need a single while loop for the query. We would need to see the updated code to be able to help you figure out why you're not getting the expected output. :) – WebElaine May 10 '18 at 13:58
0

Yup.

What you're looking for is a smart "counter".

In actuality, your issue is this:

You're trying to avoid duplicate posts.

Here's the popular method to do it.

In every file that you run a query, you must add this code:

global $duplicated_posts;

$args = [
    'post_type' => 'post',
    'post__not_in' => $duplicated_posts
];

$query = new \WP_Query($args);

Notice the post__not_in. Now, this file will be ran once (assume in a page builder, but doesn't matter) when you include it, let's keep going.

"Okay but the array is still empty".

When you actually check if you have posts, you must add each post's ID that you found to that global array, like so:

if( $query->have_posts() ) : ?>
    <div class="official-matters-group">
        <div class="official-matters-tabs">
        ..etc
        <?php
        while( $query->have_posts() ) :
            $query->the_post();
            $duplicated_posts[] = get_the_ID(); //golden ticket
            ..code for each post goes here.

So, now, when your next content box looks at this $duplicated_posts, it'll know not to include these posts.

Remember, you have to copy this pattern in every file that you want to not have repeated items!

Cheers.

0

After a long time we found the solution. Maybe it will help somebody in the future.

  <div id="collapse-official-matters" class="col-xl-12">
       <div class="official-matters-group">

         <?php $args = array('post_type' => 'official-matters', 'showposts' => 20, 'orderby' => 'date', 'order' => 'ASC',); $the_query = new WP_Query( $args ); ?>
         <?php $i = 0; $row = 0;
          while ( $the_query->have_posts()) {

            $the_query->the_post();
            if ($i === 4) {
              $i = 0;
              $row++;
            }

            $postsData[$row]['tabs'][$i] = [
              'id' => get_the_id(),
              'thumbnail' => get_the_post_thumbnail_url(),
              'title' => get_the_title()
            ];

            $postsData[$row]['content'][$i] = [
              'id' => get_the_id(),
              'excerpt' => get_the_excerpt()
            ];

            $i++;
          }
         ?>

         <div id="accordion">
         <?php foreach($postsData as $key => $value) :
           $tabs = $value['tabs'];
           $contents = $value['content'];
           ?>
             <div class="customRow">
               <?php foreach($tabs as $key => $value) : ?>
                 <div class="info-tab col-xl-3">
                   <div class="info-img">
                     <img src="<?php echo $value['thumbnail'] ?>" />
                   </div><!-- .news_img -->
                   <a data-toggle="collapse" data-target="#collapse-<?php echo $value['id'] ?>" href="#collapse-<?php echo $value['id'] ?>" class="info-title collapsed" role="button" aria-expanded="false" aria-controls="collapse-<?php echo $value['id'] ?>">
                     <?php echo $value['title'] ?>
                   </a><!-- .info-title -->
                 </div><!-- .info-tab -->
               <?php endforeach; ?>

               <?php foreach($contents as $key => $value) : ?>
                 <div class="official-matters-content">
                   <div class="info-tab-content collapse" id="collapse-<?php echo $value['id']; ?>" data-parent="#accordion">
                     <div class="card card-body">
                       <?php echo $value['excerpt'] ?>
                     </div><!-- .card -->
                   </div><!-- .info-tab-content -->
                 </div><!-- .official-matters-content -->
               <?php endforeach; ?>
             </div>
           <?php endforeach ;?>
       </div>
         <?php wp_reset_postdata(); ?>

         <?php if (false) : ?>
         <?php while ( $the_query->have_posts() ) : $the_query->the_post(); ?>
               <div class="info-tab col-xl-3">
                 <div class="info-img">
                   <?php the_post_thumbnail(); ?>
                 </div><!-- .news_img -->
                 <a data-toggle="collapse" href="#collapse-<?php the_ID(); ?>" class="info-title" role="button" aria-expanded="false" aria-controls="collapse-<?php the_ID(); ?>">
                   <?php the_title(); ?>
                 </a><!-- .info-title -->
               </div><!-- .info-tab -->

               <div class="official-matters-content">
                 <div class="info-tab-content collapse" id="collapse-<?php the_ID(); ?>">
                   <div class="card card-body">
                       <?php the_excerpt(); ?>
                   </div><!-- .card -->
                 </div><!-- .info-tab-content -->
               </div><!-- .official-matters-content -->


         <?php
           endwhile;
           wp_reset_postdata();
         ?>
       <?php endif; ?>

       </div><!-- .official-matters-group -->
    </div><!-- .collapse-official-matters -->

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.