Merge structure object with template object

I am putting together a new website for my trail-running club and one aspect of it is a calendar of events. This calendar stores both club events as well as other races put on by other entities. I have the information (Run name, date, distance, etc.) stored in a structure object, which works well and is appropriate. For now, I have put the club-owned events in this structure object as well.

However, these club-owned events also have their own pages on our site and it would be more elegant to pull the data from those and merge them with the data in the structure field for the non-club-owned events. Here is the code on the calendar.php page

<?php $events = $page->events()->toStructure()->sortBy('date', 'asc'); ?>

<?php $club_events = page('events')->children()->visible()->sortBy('date', 'asc') ?>

I wish to merge $events and $club_events and then loop through the results. Since one is a structure object and the other a template object, this cannot be done.

Thanks,

Keith

I think you better build 2 arrays with the fields you actually need from the pages and the structure, and merge those. Afterwards you could cast that merged array into a structure if you’ld like to stick with Kirby idiosyncrasies.

There are several toArray() helper methods that can help you getting there.

Another option would be to create virtual pages from those structure items in a page model, and then merge those virtual pages with the real pages.

Thank you @bvdputte. This sounds like a good approach. I’ve now merge the arrays. Can you give me a hint how to convert that merged array to a structure object?

Thanks,

Keith

Hi Keith,

Sure: $myCollection = new Structure($array); should do the trick (untested).

OK, I am testing with just the club events for now. These each have their own pages with title(), date(), etc. fields.

$club_events = page('events')->children()->visible()->toArray()
$items = new Structure($club_events)

But when I <?php dump($items) ?> I get

Kirby\Cms\Structure Object
(
    [0] => events/a
    [1] => events/b
    etc...
)

I can I access the title(), date(), etc. of those pages?

Thanks,

Keith

The dump method is not really useful here to see what you get… You would have to convert to array again to see what’s in there…

On a side note, I wouldn’t use the complete page collection, but only the content:

$club_events = page('events')->children()->listed()->toArray();
$content = A::pluck($club_events, 'content');
dump($content);

(Try to avoid visible() etc. as this method is deprecated)

Thank you @bvdputte and @texnixe for your help. For the record, and in case this may benefit others, here is what I ended up with:

Here are the relevant bits of code from the calendar.php template which lists a bunch of running events, some related to our running club (each of which has its own page) and other external events that are stored in a structure field in the calendar.txt page.

<?php $events = $page->events()->toStructure()->toArray(); ?>
<?php $club_events = page('events')->children()->visible()->toArray(); ?>
<?php $club_events = A::pluck($club_events, 'content'); ?>
<?php $merged_events = A::merge($events,$club_events) ?>
<?php $items = new Structure($merged_events) ?>
<?php $items = $items->sortBy('date', 'asc') ?>

And then loop through the results (displaying titles, URLs, etc.) of each event.

Thank you again for the ideas and tips. I couldn’t have done this without your help!

1 Like