Sort a pages object based on a calculated "next date"

Hi there.

I have a site with project pages. Each of this project has a structure field where data for (concert) shows can be entered, including a date.

Now, depending on when the panel page is opened some of these dates are still in the future and some are already in the past.

I now need to extract the next upcoming date for each page. I managed to do that with this page method:

Kirby::plugin('my/methods', [
  'pageMethods' => [
    'nextdate' => function() {
      return $this->shows()->toStructure()->filter(function ($entry) {
        return $entry->date()->toDate() > time();
      })->sortBy('date', 'asc')->first()->date();
    }
  ]
]);

Ok, this works, so I calculated a virtual nextdate value.

Now, for a pages list that I created with the k3-pagesdisplay-section plugin, I need to sort a pages object by this virtual nextdate value. I already filtered out all the shows that have no future dates, so you can assume that each page in my pages collection has at least one futre date that could be calculated as the next date.

However, I don’t understand how can I use the sortBy method to calculate by these virtual value, especially when they are within a pages collection.

Can somebody help me? If something is unclear, please tell me what to clarify.

Thanks!

Do I have to do something like, save all the pages as single page objects into an array, along with their nextdate, then sort them via some PHP methods and then in a loop re-add each single page to a new pages object? Is that the way to go about it? Or is there an easier, more kirby-like way?

https://getkirby.com/docs/guide/templates/page-models

You can solve with page models and here sample:

Page model

<?php
class ProjectPage extends Page {
  public function nextDate() {
    return date('Y-m-d H:i:s', strtotime('+1 month'));
  }
}

And use like that:

->sortBy('nextDate', 'asc')

It doesn’t even need that additional model, although you could replace the page method with a page model.

So sortBy('nextdate', 'desc') should already work without any additional stuff.

That didn’t even cross my mind. But now that I think about it, it makes sense (and also, it works).

Nice, so I basically implemented it, without knowing it. :laughing:

One last question: What is the difference then between page methods and page models? Page models only alter a certain type of page (like project), right? Is that the only difference?

Yes, that’s right, page models only apply to a single page type. There is another difference though: A page model extends Kirby’s page class, you can therefore override methods of the page class. For examples, check out ourVirtual Pages guide, where we override the children method in some examples to create subpages from external sources or modify the writeContent() method (database example) to be able to write to a database instead of the file system from the Panel.

You cannot do that with page methods.

1 Like

Perfect. Thanks for the explanation. Slowly I am getting to know all the Kirby features. Controllers, Hooks, Object Methods, Object Models: I am not afraid of you anymore. :wink:

:joy: