Group and sort by year past, current, incomming

Hi,
I have to set this type of entries :

  • Incomming
    • project 1
    • project 2
  • Now
    • project 3
    • project 4
  • Past (this year)
    • project 5
    • project 6
  • Past (< this year)
    • 2019
      • project 7
      • project 8
    • 2018
      • project 9
      • project 10

The hard part for me is to separate past projects from this year and < year and for previous year, I have to sort projects by years.

<?php
  $groups = $site->find('programme')->children()->listed()->sortBy('date_start', 'desc')->group(function($article) {
     $today = date('Y-m-d');
     $datestart =  $article->date_start()->toDate('Y-m-d');
     $dateend =  $article->date_end()->toDate('Y-m-d') ;
     $datearray =  getDatesFromRange($datestart, $dateend);

    if(in_array($today, $datearray)) return 'En cours';
    if($datestart > $today)   return 'a venir';
    return 'passe';
  });
?>

<?php foreach($groups as $description => $items): ?>

<ul class="container">
   <?php foreach($items->sortBy('date_start', 'desc') as $page): ?>
   
   <?php if($description == 'a venir'): ?>
   <li class="grid-item avenir">  
       ... Incomming
   </li>

   <?php elseif($description == 'passe'): ?>
   <li class="grid-item passe">  
      ... Past
   </li>
   
   <?php else: ?>
  <li class="grid-item">  
   ... Current
   </li>
   <?php endif ?>

   <?php endforeach ?>
</ul>

<?php endforeach ?>

With these lines, I get only this type of sorting

  • Incomming

    • project 1
    • project 2
  • Now

    • project 3
    • project 4
  • Past (every years)

    • project 5
    • project 6
    • project 7
    • project 8
    • project 9
    • project 10

Current year:

if ($dateend < date('Y-m-d') && $article->date_end()->toDate('Y') === date('Y') return 'This year'

Great, this works to separate this year from previous.
Now, to list every projects separately by years from previous year, how can I list every projects inside the if($pastyears) condition ? Do I need to set another foreach outside the first one or is there a nice method to sort them by year inside the main foreach ?

You could group the items in the past years group again… But the order of your foreach and if statements is a bit weird, because you loop before you output the headline.

The code should probably look something like this:

<?php foreach ($groups as $description => $items) : ?>

<ul class="container">
  <li class="grid-item <?php echo Str::slug($description) ?>">  
    <?php echo $description ?>
  </li>
  <?php if ($description === 'passe') :
    $groupedItems = $items->group(function($child) {
      return $child->dateend()->toDate('Y');
    }); 
  ?>
    <?php foreach ($groupedItems as $year => $items): ?>
      <li class="grid-item <?php echo Str::slug($year) ?>">  
      <?php echo $year ?>
      </li>
      <?php foreach ($items as $item) : ?>
        <!-- Code for the year item -->
      <?php endforeach ?>
    <?php endforeach ?>
  <?php else: ?>

  <?php foreach($items->sortBy('date_start', 'desc') as $page): ?>
    <!-- code for page -->
  <?php endforeach ?>
  <?php endif ?>
  
</ul>

<?php endforeach ?>

( with proper markup, because what we have here doesn’t look correct for the nested lists).

Thanks a lot Sonja for lighten my brain ! Keep safe, bye