Create a Collection of virtual pages on the fly

,

Hi everybody.

I’ve got a calendar view where I group events by month.

Within this events list (that exist as real pages), I’d also want to insert some “special events” that doesn’t exist as pages. They occur the first Saturday of each month (during the time where the events take place).

Within my controller:

// helper 
function getFirstSaturdayOfMonth($year, $month) {
    $date = new DateTime("$year-$month-01");
    $date->modify('first saturday of this month');
    return $date;
}

// extract all dates
$all_dates = $current_and_future_events->pluck("start_date");
// or test with
$all_dates = [
    '2025-09-15',
    '2025-10-20',
    '2026-02-11',
    '2026-04-25',
];

// convert dates to DateTime
$eventDates = array_map(function($date) {
  return new DateTime($date);
}, $all_dates);
// get min and max
$firstDate = min($eventDates);
$lastDate = max($eventDates);

// create an empty collection
$saturdaysCollection = new Pages();

// loop over the dates between the first and last event date (I struggled a lot on this loop…)
for ($currentMonth = $firstDate->format('Y-m'); $currentMonth <= $lastDate->format('Y-m'); $currentMonth = (new DateTime("$currentMonth-01"))->modify('first day of next month')->format('Y-m')) {
  list($year, $month) = explode('-', $currentMonth);
  $firstSaturday = getFirstSaturdayOfMonth($year, $month);
  
  // skip if the first Saturday is before the first event date
  if ($firstSaturday >= $firstDate) {
      // create the virtual page
      $virtualPage = new Page([
        'slug' => 'saturday-' . $firstSaturday->format('Y-m-d'),
        'template' => 'event', 
        'start_date' => $firstSaturday->format('Y-m-d'),
        'url' => "/some-static-page-about-first-saturdays",
        'title' => 'Portes ouvertes des ateliers'
      ]);

      // Add the virtual page to the collection (should I use `append`?)
      $saturdaysCollection->add($virtualPage);
  }
}

// group together real events and virtual ones
$allrendezvous = $current_and_future_events->add($saturdaysCollection)->sort(function($child){
  $start_date = $child->start_date()->toDate("%Y-%m-%d");
  return $start_date;
});

But the $saturdaysCollection seems to only contain strings (saturday-2025-10-04’), and not pages (even if virtual pages seem to be ok).

The overall logic is quite complex, but I cannot understand how to deal with this kind of virtual pages / collections.

Thanks in advance for your help.

What makes you think so?

Looks ok to me, apart from the stuff with the title, which should be inside the content array. And you shouldn’t add the url prop.

Oh! I missed the content array…

$virtualPage = new Page([
  'slug' => 'saturday-' . $firstSaturday->format('Y-m-d'),
  'template' => 'event', 
  'content' => [
    'start_date' => $firstSaturday->format('Y-m-d'),
    'details_page_url' => "/some-static-page-about-first-saturdays",
    'title' => 'Portes ouvertes des ateliers'
  ]
]);

The url prop should also go within content, but renaming it might be wise.

Thank you @texnixe!