Find and FilterBy Filename

Happy New Year!

Hopefully you can point me to a solution for my project.

I want to create a filterBy function that finds the first part of the filename (anything before the “_”) and group them together.

My files looks like this:

A_1.zip
A_2.zip
A_3.zip
B_1.zip
B_2.zip
C_1.zip

and I want to output this:

A
B
C

Looked at the “*=”, “<” filter methods without luck.
Any help is much appreciated!

X

I think you can use the group function for this.

<?php

$yourfiles = $page->files()->group(function($f){
  return substr($f->filename(), 0);
});

foreach ($yourfiles as $letter => $letterList): ?>
  <h2><?= $letter ?></h2>
  <ul>
    <?php foreach($letterList as $file): ?>
      <li><a href="<?= $file->url() ?>"><?= $file->filename() ?></a></li>
    <?php endforeach ?>
  </ul>
<?php endforeach ?>

I did not test this but I think it should work.

amazing going to give it a try! thanks for the quick response.

for some reason getting “an unexpected error”. trying to trouble shoot but not sure what could be causing this.

I tried it myself by adding some images to a blank Kirby installation. I got an error too. I think what’s happening is that it’s not possible to group() the $page->files() array.

If you convert it to a collection it works:


<?php

$files = $page->files();
$fileCollection = new Collection();

foreach ($files as $file) {
  $fileCollection->append($file->filename(), $file);
}

$fileCollection = $fileCollection->group(function($f) {
  return substr($f->filename(), 0, 1);
});

foreach ($fileCollection as $letter => $letterList): ?>
  <h2><?= $letter ?></h2>
  <ul>
    <?php foreach($letterList as $file): ?>
      <li><a href="<?= $file->url() ?>"><?= $file->filename() ?></a></li>
    <?php endforeach ?>
  </ul>
<?php endforeach ?>

But I’m pretty sure this can be achieved a lot easier and cleaner. @texnixe?

I would have expected the files object to inherit the method from the collection class. Apparently, that’s not the case. I have created an issue on GitHub.

I thought so too and that’s why I blindly suggested it.

As long as this is not directly possible, do you know of an easier way of converting the files() to a collection without the foreach loop?

Unfortunately, I don’t know of any alternative to your code suggested above.