dear community,
I got stuck with following issue:
the plan is to get an overview/programme/lineup of all project-dates - the projects are child pages and each project-page contains a structure field with date / time / location …
@texnixe helped me a lot sorting things out - see here:
finally it works
this is my collection-file:
<?php
return function ($site) {
$projects = $site->find('produktionen')->children()->listed();
$collection = [];
foreach ($projects as $project) {
foreach ($project->termine()->toStructure() as $item) {
$collection[] = [
'slug' => $project->slug() . '-' . $item->datum()->toDate('EE, dd. MMM YYYY'),
'template' => $project->intendedTemplate()->name(),
…
I’d like to have the output like this:
September 2022 (month)
23. (day)
Project A, 20:00
Project B, 21:00
Oktober 2022
and so on ...
with my current code it looks like this:
September 2022 (month)
23. (day)
Project A, 20:00
Project B, 21:00
Oktober 2022
Oktober 2022
I’d like to group the months like the days … I’ve tried it with group function but without success :-/
this is my template:
<?php $kirby->collection('lineup'); ?>
<?php foreach ($kirby->collection('lineup') as $date => $items):
$groupedMonths = $items->sortBy('datum')->group(function($p) {
return $p->datum()->toDate('Y-m');
}); ?>
<h3>
<?= $groupedMonths ?>
</h3>
<?php
$groupedDays = $items->sortBy('datum')->group(function($p) {
return $p->datum()->toDate('d.');
}); ?>
<p>
<?= $groupedDays ?>
</p>
<?php foreach ($items as $project): ?>
<?= $project->title() ?>
<?= $project->untertitel(); ?>
<?= $project->zeit() ?>
<?= $project->zusatz() ?>
<?php endforeach ?>
<?php endforeach ?>
this is my collection:
<?php
return function ($site) {
$projects = $site->find('produktionen')->children()->listed();
$collection = [];
foreach ($projects as $project) {
foreach ($project->termine()->toStructure() as $item) {
$collection[] = [
'slug' => $project->slug() . '-' . $item->datum()->toDate('Y-m-d'),
'template' => $project->intendedTemplate()->name(),
'content' => array_merge(
$project->content()->toArray(),
['datum' => $item->datum()->toDate('Y-m-d'),
'zeit' => $item->zeit(),
'zusatz' => $item->zusatz()]
),
];
}
}
return Pages::factory($collection)->sortBy('datum', 'asc')->groupBy('datum', 'asc');
};
any help would be appreciated!
You need to group the collection by month in this case, then within each month collection, group by day.
So you got to start at the collection definition.
so do I need to create two different collections - one for months and one for days?
I tried to create a collection for months, but I am not sure, if this is correct …?
this is the dump
output:
Array
(
[0] => Array
(
[0] => 2022-12
)
[1] => Array
(
[0] => 2022-12
)
[2] => Array
(
[0] => 2022-12
)
[3] => Array
(
[0] => 2023-01
)
[4] => Array
(
[0] => 2023-01
)
[5] => Array
(
[0] => 2023-01
)
[6] => Array
(
[0] => 2023-01
)
[7] => Array
(
[0] => 2023-01
)
[8] => Array
(
[0] => 2022-09
)
[9] => Array
(
[0] => 2022-09
)
[10] => Array
(
[0] => 2022-10
)
[11] => Array
(
[0] => 2022-10
)
[12] => Array
(
[0] => 2022-10
)
[13] => Array
(
[0] => 2022-10
)
)
this is the collection month.php:
<?php
return function ($site) {
$projects = $site->find('produktionen')->children()->listed();
foreach ($projects as $project) {
foreach ($project->termine()->toStructure() as $item) {
$collection[] = [
$item->datum()->toDate('Y-m')
];
}
}
return $collection;
};
I am not sure, but I think things like sortBy and groupBy don’t work with arrays …?
thx for any advice!
Why didn’t you create the collection exactly as originally, with the only difference being the date formated by Y-m instead Y-m-d?
Yes, of course not, sortBy and groupBy are member methods of their class and can only be used with objects or that class.
yes, that’s what I tried first, but then I got the following output (with the template I postet above):
2022-09 (month)
(day)
Project A
Project A
2022-10 (month)
(day)
Project A
Project B
and so on …
it seems $groupedDays
can`t get the whole date …?
Sorry, I got confused myself now.
The collection has to be created a originally with the full date. But then do not group the collection or group by month:
<?php
return function ($site) {
$projects = $site->find('produktionen')->children()->listed();
$collection = [];
foreach ($projects as $project) {
foreach ($project->termine()->toStructure() as $item) {
$collection[] = [
'slug' => $project->slug() . '-' . $item->date()->toDate(),
'template' => $project->intendedTemplate()->name(),
'content' => array_merge(
$project->content()->toArray(),
['date' => $item->date()->date('Y-m-d')]
),
];
}
}
return Pages::factory($collection)->sortBy('date')->groupBy('date');
woyzeck
7d
finally :grinning: it works :wink:
this is my collection-file:
<?php
return function ($site) {
$projects = $site->find('produktionen')->children()->listed();
$collection = [];
foreach ($projects as $project) {
foreach ($project->termine()->toStructure() as $item) {
$collection[] = [
'slug' => $project->slug() . '-' . $item->datum()->toDate('EE, dd. MMM YYYY'),
'template' => $project->intendedTemplate()->name(),
'content' => array_merge(
$project->content()->toArray(),
['datum' => $item->datum()->toDate('EE, dd. MMM YYYY'),
'zeit' => $item->zeit(),
'zusatz' => $item->zusatz()]
),
];
}
}
return Pages::factory($collection)->sortBy('datum', 'asc');
};
With that you have a standard ungrouped pages collection, one page for each date.
Now in your template, you can group this collection by month:
<?php $collection = collection('mycollection'); ?>
<?php foreach($collection->group(fn ($p) => $p->date()->toDate('Y-m')) as $month => $items): ?>
<?= $month ?>
<?php foreach ($items->groupBy('date') as $day => $dayItems) : ?>
<?= $day ?>
<?php foreach ($dayItems as $event): ?>
<?= $event->title() ?>
<?php endforeach ?>
<?php endforeach ?>
<?php endforeach ?>
(Not tested)
good morning and thx again for your patience!
the collection works as expected:
Kirby\Cms\Collection Object
(
[0] => 2022-09-29
[1] => 2022-09-30
[2] => 2022-10-01
[3] => 2022-10-06
[4] => 2022-10-07
[5] => 2022-12-16
[6] => 2022-12-17
[7] => 2022-12-31
[8] => 2023-01-06
[9] => 2023-01-07
[10] => 2023-01-12
[11] => 2023-01-13
[12] => 2023-01-14
)
unfortunately i get an error Call to a member function toDate() on null
for this line:
<?php foreach($collection->group(fn ($p) => $p->date()->toDate('Y-m')) as $month => $items): ?>
this seems to be really tricky …
Rather you seem to have named the field differently maybe, datum instead of date?
woyzeck
December 4, 2022, 9:10am
10
yes I did, but I edited the names according to my field-names …
texnixe
December 4, 2022, 9:12am
11
If you want, send me a download link via PM to your project, then I can look into it instead of having to set up a test case myself.
woyzeck
December 4, 2022, 10:10am
13
it works!!!
deleting ->groupBy('date')
in the collection brought success!
THX A LOT!!!