How to compare 'pages' fields and output a list of related posts that have one or more of the same pages attached

Hi there,
I’ve found myself stuck again! I have blog posts that each have a ‘pages’ field (‘relatedsteps’) so that the posts can be tagged with related ‘steps’ (they are the steps of a process - pages elsewhere in the site). What I want to do is on each blog post compare the ‘relatedsteps’ and output related blog posts that have one or more of the same steps selected. I’ve gone down a bit of a rabbit hole with this and have ended up converting the related posts to an array so that I can use array_unique to output a list of the related posts that aren’t repeated. However, I’m now getting errors about ‘array to string conversion’ on the ‘array_unique’, and also then I don’t really know how to use the array to then output the title and url of each post.

Here is the code at the moment:

    $relatedsteps = $page->relatedsteps()->toPages();
    $posts = array();

    foreach($relatedsteps as $relatedstep):
      $theseposts =
                  $page->siblings($self = false)->filter(function($sibling) use($relatedstep) {
                  return $sibling->relatedsteps()->toPages()->has($relatedstep);
        if($theseposts->isNotEmpty()) {
          if($theseposts->count() > 1) {
            $theseposts = $theseposts->toArray();
            $posts = array_unique(array_merge($posts, $theseposts));
          } else {
            $posts = array_unique(array_push($posts, $theseposts));



How do I fix the ‘array to string conversion’ error? Or is there a better way of doing this where I can keep everything as a pages collection?

Thanks very much in advance,

This should work:

$relatedsteps    = $page->relatedsteps()->toPages();
$relatedSiblings = $page->siblings(false)->filter(function($sibling) use($relatedsteps) {
    return $sibling->relatedsteps()->toPages()->intersection($relatedsteps) > 0;

Ah I did not know about ‘intersection’ - that makes things much simpler, thank you @pixelijn !

Sorry @pixeljin, just to clarify, do I need the > 0 bit at the end of your code? It throws an error (Object of class Kirby\Cms\Pages could not be converted to int), so I deleted, but now I’m not actually sure it’s filtering the siblings - things that have no ‘related steps’ are still showing up in the list :confused:

Thanks again for your help,

I forgot the count() bit, but checking if the collection is empty works just as well:

 return $sibling->relatedsteps()->toPages()->intersection($relatedsteps)->isNotEmpty();