Events from remote pages

Hi,

maybe I understand something wrong in PHP (I’m not a programmer), so I always struggling with cases like this. Now, for example there is need to do a calendar of events on a page, and build it up from fields which are in structure fields in “project” pages (children of “projects” page). Here is one of my attempts, which doesn’t work properly (it make only one event).

<?php
$projects = page('projects')->children();
foreach($projects as $project); ?>

<ul>
	<?php foreach($project->events()->toStructure() as $event): ?>
		<li>
			<?= $eventPage->title()->html() ?>
			<?= $event->date()->toDate('d. m. Y') ?>
			<?= $event->venue()->html() ?>
			<?= $event->category()->html() ?>
		</li>
	<?php endforeach ?>
</ul>

or, for example:

<ul>
	<?php 
		foreach(page('projects')->children()->listed() as $eventPage);
		foreach($eventPage->events()->toStructure() as $event2): ?>
			<li>
				<?= $eventPage->title()->html() ?>
				<?= $event2->date()->toDate('d. m. Y') ?>
				<?= $event2->venue()->html() ?>
				<?= $event2->category()->html() ?>
			</li>
		<?php endforeach ?>
</ul>

Also, I always feel like I do things more complicated than it’s necessary, so I would appreciate any good guidelines or something!

Thank you so much!

There’s a second endforeach missing in both examples. Both versions are possible depending on whether or not you want to start a new list per project or not.

In your first example

is not defined. Change it to $project.

Oh no, my unnecessary mistake! Thanks!
This works perfect for my:

<ul>	
<?php
	$projects = page('projects')->children();
	foreach($projects as $project): 
	foreach($project->events()->toStructure() as $event): ?>
		<li>
			<?= $project->title()->html() ?>
			<?= $event->date()->toDate('d. m. Y') ?>
			<?= $event->venue()->html() ?>
			<?= $event->category()->html() ?>
		</li>
	<?php endforeach ?>
	<?php endforeach ?>
</ul>

But, if I try to short it a little, there is always some problem:

<ul>	
	<?php
	$events = page('projects')->children()->events()->toStructure();
	foreach($events as $event): ?>
		<li>
			<?= $project->title()->html() ?>
			<?= $event->date()->toDate('d. m. Y') ?>
			<?= $event->venue()->html() ?>
			<?= $event->category()->html() ?>
		</li>
	<?php endforeach ?>
</ul>

In your second new example change

to $event->parent().

<?php
$projects = page('projects')->children();
foreach($projects as $project); ?>

<ul>
	<?php foreach($project->events()->toStructure() as $event): ?>
		<li>
			<?= $event->title()->html() ?>
			<?= $event->date()->toDate('d. m. Y') ?>
			<?= $event->venue()->html() ?>
			<?= $event->category()->html() ?>
		</li>
	<?php endforeach ?>
</ul>
<?php endforeach ?>

This solution return only one event to the list. So I’m still using the first one, which is almost good. But, there is one issue on that (which is maybe connected with your suggestion) – It looks like events are still together in projects. Because I have tried to sort it, and the items from particular project are still together. So, sorting works only “inside” projects and don’t affect whole list.

Here is current code with sorting:

<ul>	
<?php
	$projects = page('projects')->children();
	foreach($projects as $project): 
		foreach($project->events()->toStructure()->sortBy('date') as $event): ?>
			<li>
				<?= $project->title()->html() ?>
				<?= $event->date()->toDate('d. m. Y') ?>
				<?= $event->venue()->html() ?>
				<?= $event->category()->html() ?>
			</li>
		<?php endforeach;
	endforeach ?>
</ul>

Thank you!

It seems to me that you haven’t enable debugging in your config.phpfile. I recommend you do that while developing: https://getkirby.com/docs/reference/system/options/debug

Thanks, I’m trying tu use debug mode, also var_dump. But the main issue remains – events are sorted only inside project. I understand that the nested foreach is probably making it, but I’m just looking if there is some easy way to prevent it with Kirby PHP API.

Last version is here
    <ul>
    <?php	
    	foreach(page('projects')->children() as $projectPage):
    		foreach($projectPage->events()->toStructure()
    					->sortBy('date', 'asc')
    					->filter(function ($page) {return $page->date()->toDate() > time(); })
    				as $event): ?>
    			<li>
    				<span><?= $event->date()->toDate('j/n/y') ?></span>
    				<span><?= $event->category()->html() ?></span>
    				<span style="background-color:<?= $event->parent()->color()->html() ?>;">
    					<a href="<?= $event->parent()->url() ?>">
    						<?= $event->parent()->title()->html() ?>
    					</a>
    				</span>
    				<span><?= $event->venue()->html() ?></span>
    			</li>
    		<?php endforeach;
    	endforeach			
    ?>
    </ul>

Yes, if you want all events sorted and not by project, you first have to collect them all into one big collection then sort them.

That is the thing. I’m trying something like:

<ul>
<?php	
		$events = page('projects')->children()->events()->toStructue();
		foreach($events()
					->sortBy('date', 'asc')
					->filter(function ($page) {return $page->date()->toDate() > time(); })
				as $event): ?>
			<li>
				<span><?= $event->date()->toDate('j/n/y') ?></span>
				<span><?= $event->category()->html() ?></span>
				<span style="background-color:<?= $event->parent()->color()->html() ?>;">
					<a href="<?= $event->parent()->url() ?>">
						<?= $event->parent()->title()->html() ?>
					</a>
				</span>
				<span><?= $event->venue()->html() ?></span>
			</li>
		<?php endforeach			
?>
</ul>

But obviously it’s not possible to get events from all pages from page(‘projects’) this way.

No, you would have loop through all children first, then fetch the individual structure items, add them to a new structure.

I think I’ve done something like that before, I’ll try to find the code. There should actually be a code snippet here on the forum somewhere.

I’ve been looked for some solution here on forum, but still have no idea.

For me, those nested arrays are pretty complicated and if there are not any easy solution in Kirby API, then maybe something is wrong in my structure, maybe in general. Would do I better if for example the events will store on other place in structure? Separated from project pages? Obviously, for my client it would be appropriate to add events in panel to corresponding Projects, but maybe I miss something …

Thank you for any tips

Finally, I fixed this issue with some changes in structure. Events are subpages of their projects now. So, structure is maybe a little more complicated but call and list all events to calendars is much, much easier.
Thank you everyone for help.