Project groups based on tag – Show random group on reload

I’m trying to have a page called Projects where all Projects are shown and not grouped or sorted. Every project can get one or more tags.
Now I would like to group those projects by their tags and show one project group on each reload on the Home page. Since a project can have more than one tag, it is possible, that one project is in more than one group.

Project 1 – Tags: Red, Green
Project 2 – Tags: Red
Project 3 – Tags: Green
Project 4 – Tags: Green, Blue
Project 5 – Tags: Red

Groups: Red, Green, Blue

Finally the shown and grouped projects on the home page would be limited to 3 and each page reload, a random other group will be shown. So in the end, the groups contain 3 random projects with one tag which they have in common.

One idea was, that I just sort the projects based on the similar tags and then show the first 3 of this sorted list. Then I would only need to shuffle this sorted list every page reload, right?

I have this projects-snippet:

  <?php foreach ($projects as $project): ?>
    <section class="swiper-container">
      <div class="swiper-wrapper">
        <?php foreach ($project->images()->sortBy('sort') as $image): ?>
        <div class="swiper-slide">
          <?= $image ?>
        </div>
        <?php endforeach ?>
      </div>
      <div class="swiper-button-prev"></div>
      <div class="swiper-button-next"></div>      
    </section>
  <?php endforeach ?>

The snipped above is then used on the Home page like this:

<?php snippet('header'); ?>

<div class="wrapper projects">
  <?php snippet('projects', [
    'projects' => page('projects')
      ->children()
      ->listed()
      ->sortBy('tags', 'tag', ',')
      ->limit(3)
  ]); ?>
</div>

<?php snippet('footer'); ?>

I’m new to Kirby and php and searched the forum for similar problems. I tried to work with sortBy, filterBy and groupBy, but it always seems that I miss something to make it really work. Would the Similar Plugin be a necessary tool for that?

What I would do:

<?php
$projects = page('projects')->children()->listed();
// get an array with all unique tags
$tags = $projects->pluck('tags', ',', true);
// shuffle array and get first element
$tag = A::first(A::shuffle($tags));
// filter subpages by random tag and get first three elements
$filteredProjects = $projects->filterBy('tags', $tag, ',')->limit(3);
foreach ($filteredProjects as $project) : ?>
<!-- do stuff here -->
<?php endforeach ?>

Ideally, the logic goes into a controller and the $filteredProjects are returned to the template.

2 Likes

Oh wow! That was fast. It works perfectly, thank you so much!
Once I was close with the pluck, but then I messed up be tag-shuffle.