Filter pages by year

Hi, I am using kirby for the first time to update my portfolio site and generally speaking I like it a lot!
Since I am not a developer I got stuck on an issue that is taking me quite some time to figure out:
I want to implement several pages that show the projects that I have done in a given year:

<?php $items = $pages->find('work')->children()->visible()->filter(function ($child) {  
return $child->published()->toDate('Y') == '2019';
}); ?> 

It works as long as I put in a fixed year (so I know it is working), but I need to access the different years form the date-field (that in my case is calles “published”) dynamically.

I have tried several things like:

<?php $items = $pages->find('work')->children()->visible()->filter(function ($child) { return $child->published()->toDate('Y') == print_r($page->published()->toDate('Y')); }); ?>

or

<?php $items = $pages->find('work')->children()->visible()->filter(function ($child) { return $child->published()->toDate('Y') == '$page->published()->toDate('Y')'; }); ?>

but I am stuck here, probably because the lack of some simple syntax knowledge.

Could you please point me in the right direction?
Thanks in advance!

If I understand you correclty, you want to list pages out grouped by year, and you are using Kirby 3?

You can group your collection by year using the group() method with a callback

<?php
$callback = function($p) {
  return $p->published()->toDate('Y');
};

$groups = $pages->find('work')->children()->listed()->group($callback); 

foreach($groupedItems as $year => $itemsPerYear): ?>
    <h2><?= $year ?></h2>
    <ul>
      <?php foreach($itemsPerYear as $item) : ?>
      <li><?= $item->title() ?></li>
      <?php endforeach; ?>
    </ul>
<?php endforeach ?>

Adapt the HTML to your liking.

Please note that visible() is deprecated in Kirby 3, use listed() instead.

3 Likes

yeah sorry if I did not explain it well: if have several pages like 2019, 2018, and 2017 … that show the projects that have been done in these years.

the test-site is here https://kirby.fznfrzn.de/

Ok, but if they are sub pages to pages called 2018, 2019 etc, im not sure that you need the grouping since you have sorted them already into subfolders?

Great! I will try to implement it this way!

Right, then no filtering is needed and you can just output them in the order they appear.

Meaning, you’d loop through the year parents and for each parent output the children. Then grouping won’t make sense in this case.

See my edited post.

no, they are not subpages, they share the same level. I use two different templates in /work:
“project” and “year” - so I guess that grouping is the way I should try!

But you have urls like this https://kirby.fznfrzn.de/work/2018… cant you just list out the children?

What’s the purpose of the year folders then? Could you post your folder structure?

I like to have the masonry grid structured visually by years, so that you can get an idea in which year the projects were done:
Annotation%202019-04-14%20233936
The folder structure therefor is something like:

  • work
    • project a
    • project b
    • 2019
    • project c

Guessing from your structure with year and projects on the same level, the year folders seems pretty useless, and in this case what I suggested above seems the way to go.

You should either have a structure like this

- 2019
  -- project-a
  -- project-b
- 2018
  -- project-y
  -- project-x

or no years folders at all

Sure but could you please take a screen shot of finder or explorer, or the sidebar of your code editor with folders open, since it easier for us to understand :slight_smile:

yes sure:
Annotation%202019-04-14%20234459

As I said above, I don’t see the purpose of those year folders and that setup just doesn’t make sense.

Option 1: remove the year folders and group by year (see my code above)
Option 2: put the corresponding projects into the years they belong to, then loop though years and then through the children of each year

Thanks for your ultrafast replies and the concerns about my site’s structure :grinning:
Probably I will go with option 1 and figure out a way to show the corresponding images (like 2017.jpg, 2018.jpg) instead of

<h2><?= $year ?></h2>

Option 2 would actually be a lot simpler, and as for the year image you can store it under the year folders and use the query language to fetch it if you need it in the sub pages, without duplicating the file.

thanks again :+1:t4: for helping me on this issue!