Merge arrays in for loop

Hi,

this is probably a more general PHP question.
I have two pages in kirby (experiments and thoughts). I would like to show (and mix) articles from both of them on one page.
right now I have a loop like this:

<?php foreach (page('/experiments)->children()->visible()->filterBy('date','<=',time())->sortBy('date','desc')->limit(2) as $p): ?>

How would I extend this to contain subpages from both streams? I tried array_merge until now. However without success.

Daniel

1 Like

There are two ways to merge/append to collections, here is an example:

//Merge two collections
<?php 
  $exhibitions = $pages->find('exhibitions')->visible()->children()->filterB('now', 'noo');
  $news  = $pages->find('news')->visible()->children();
  $homeflux = new Pages(array($exhibitions, $news));
?>

//Appending stuff to a collection:
<?php 
  $homeflux = new Pages();
  $homeflux->add($pages->find('exhibitions')->visible()->children()->filterBy('now', 'noo'));
  $homeflux->add( $pages->find('news')->visible()->children());
// etc...
?>

You would then use your foreach loop after having merged the collections …

1 Like

Which do you prefer? The last one?

I do not seem to get it working:
This is my code now:

<?php
  $all_pages = new Pages();
  $all_pages->add($pages->find('experiments')->children()->visible());
  $all_pages->add($pages->find('thoughts')->children()->visible());
  print_r($all_pages);
?>
<?php foreach ($all_pages->sortBy('date','desc')->limit(2) as $p): ?>

It does not print anything it does not loop…

Daniel

Where in your content tree are those two pages “experiment” and “thoughts”?

Well, up to now I was able to traverse the subpages (individually) with the following line:

<?php foreach (page('/experiments')->children()->filterBy('date', '<=', time())->visible()->sortBy('date','desc')->limit(2) as $p): ?>

Then use the same code here, but I don’t know why you need the slash, page('experiment') should work just fine.

<?php
  $all_pages = new Pages();
  $all_pages->add(page('/experiments')->children()->visible());
  $all_pages->add(page('/thoughts')->children()->visible());
  print_r($all_pages);
?>
<?php foreach ($all_pages->sortBy('date','desc')->limit(2) as $p): ?>

Or try the first option.

1 Like

Now it works! Thanks!

This is beautiful. I love this!
Is there a way to query within the loop which collection each $p comes from easily by inserting a CSS class, or something?

Well, you can get the original collection if you merge collections, but in the above example, each collection derives from the same parent, so each page has a parent that is equivalent to its original collection.

<?= ($parent = $p->parent()) ? $parent->id() : '' ?>
1 Like

You could also check if the item is in one of the collections with $collection->has().

1 Like

This works perfectly. Thanks, Sonja!
I’ll have to look into that, @lukasbestle. Thanks.