Separate all events into group of max 3 items

Hi!
I try to find a way to divide all my events into groups of maximum 3 events in each group. more specifically I want that each 3 events to get wrapped in a div. and the rest (last 2 or 1) will get wrapped too.

I started to write something and I desperately need your help:

    
  <?php   
          $nextSevenDays = strtotime("+7 day");
          $week = date('Y-m-d',$nextSevenDays) ;
          $today = date('Y-m-d');
          $events = page()->children()->template('event')
          ->filter(fn ($p) => $p->date()->toDate('Y-m-d') >= $today)
          ->filter(fn ($t) => $t->date()->toDate('Y-m-d') < $week);
          $sortedEvents = $events->sortBy('date','starts');

          $event_counter = count( $sortedEvents );
          
          while ( $event_counter > 0 ) {
              echo "<div class='three-events'>";
              for ( $i = 0; $i<3; $i++) {
                  if ( count($sortedEvents) == 0 ) break;

                  echo "<div class='event'> Title of event </div>";
              }
              
              $event_counter -= 3;
              echo "</div><br>";
          }   
  ?>

The while loop works good and it gives me the right amount of events divided correctly to 3. the problem is that I can’t insert the data from the $sortedEvents - I can’t understand how to create a variable of a single event inside the while loop. I tried to use forEach inside the if statement but it shows all the events multiple times.

I would appreciate any help!
THANKS!

Please use the Kirby 3 question category for questions, thanks!

Thanks for the reply!
I will use the kirby 3 question category from now on… :pray:

I’m sorry but I can’t understand how to use the chunk() method :confused:
I had this poor try that gives me empty divs:

  <?php   

          $nextSevenDays = strtotime("+7 day");
          $week = date('Y-m-d',$nextSevenDays) ;
          $today = date('Y-m-d');
          $events = page()->children()->template('event')
          ->filter(fn ($p) => $p->date()->toDate('Y-m-d') >= $today)
          ->filter(fn ($t) => $t->date()->toDate('Y-m-d') < $week);
          $sortedEvents = $events->sortBy('date','starts');
          $eves = $sortedEvents->chunk(4);
          foreach($eves as $event): ?>

          <div><?= $event->title()?> </div>
  <?php endforeach ?>
<?php 
// ... 

$chunks = $sortedEvents->chunk(3);
?>

<?php foreach($chunks as $chunk): ?>
    <div class="wrapper">
        <?php foreach($chunk as $event): ?>
            <article>
                <h2><?= $event->title()->html() ?></h2>
            </article>
        <?php endforeach ?>
    </div>
<?php endforeach ?>

You need 2 loops.

Also, I’d recommend that you don’t create new variables for each step.

<?php
$nextSevenDays = strtotime("+7 day");
$week = date('Y-m-d', $nextSevenDays);
$today = date('Y-m-d');

$events = page()->children()->template('event')
    ->filter(fn ($p) => $p->date()->toDate('Y-m-d') >= $today && $p->date()->toDate('Y-m-d') < $week)
    ->sortBy('date', 'starts')
    ->chunk(3); // if you want three events per chunk, it shouldn't be 4
?>
<?php foreach ($events as $chunk => $eventList) : ?>
    <div>
        <?php foreach ($eventList as $event) : ?>
            <div><?= $event->title() ?></div>
        <?php endforeach ?>
    </div>
<?php endforeach ?>

Also, you don’t need two filters but can combine the logic into one callback.

Edit: @rasteiner beat me to it… Leaving this here because of the additional information.

1 Like

Thank you so much - It works perfectly and makes much more sense!
I really appreciate your help :pray: