Filter artices by year from date field

Actually I filter articles by year this way, with a year field in the blueprint:

controllers:

if($year = param('year')) { 
$items = $items->filterBy('year', $year, ',');
 }
$years = $page->children()->listed()->pluck('year', ',', true);

and in the template:

  <ul class="years">
      <?php foreach($years as $result): ?>          
      <li> <a href="<?= url($page->url(), ['params' => ['year' => $result]]) ?>"><?= html($result) ?></a></li>     
      <?php endforeach ?>
    </ul>

 (...)

<?php if(param('year')): ?>
     <div class="">
       <h2><span><?= html($year) ?></span> <a href="<?= $page->url() ?>">x</a></h2>    
    </div>
    <?php endif ?>

What would be the best way to fetch years the same way from a date field instead?

Thank you.

if($year = param('year')) { 
    $items = $items->filter(function($item) use($year) {
      return $item->date()->toDate('Y') === $year;
    }
}

And in my case for a multilangue website and strftime I need to change to:

return $item->date()->toDate('%Y') === $year;

Thank you Sonja! I do not bother you anymore for a few weeks :innocent:

1 Like

Oh, are you going on vacation?

Did you know we have this wonderful recipe all about filtering :wink:: https://getkirby.com/docs/cookbook/content/filtering

And there are many more…

1 Like

Hmm, I would like so much! vacations are a dream…

Yes sur! But I think you overestimate my ability to understand it all :wink:

Note:
It was working because I was keeping the year field. Now I empty it, it return nothing, I’ve to search how to pluck correctly the date field :wink:

Ah, ok, but the filter code is nevertheless correct.

To get the years from the date, you can still use the pluck method if you create a page model first. Example (for a note page in the Starterkit)

<?php

class NotePage extends Page
{

    public function year()
    {

        return $this->date()->toDate('%Y');
    }

}

Then you can use the pluck method with the year method as above.

1 Like

Ok I will try it. For the moment it works with:


  if($year = param('year')) {    

    $items = $items->filter(function($item) use($year) {
      return $item->date()->toDate('%Y') === $year;
    });

  }

$years = $page->children()->listed()->pluck('date');
  $years = array_unique(array_map(function($p) {
    return date('Y', strtotime($p));
  }, $years));

I’m sur using a page model is a better alternative. Thanks for the tips.