Sorting
5, 4, 3, 2, 1…, sorting content is an everyday developer's task when dealing with all sorts of content collections: articles, events, images or similar data needs to be sorted, for example, by date or title, in descending or ascending order, or even by a more complicated sorting algorithm.
Kirby's API comes with a built-in methods for sorting: the sortBy() method. This method can be used with all sorts of collections (pages, files, users, roles, translations, structure field items etc.).
The sortBy($field, $direction = 'desc', $method = SORT_REGULAR)
method accepts three parameters:
$field
The content field or method you want to sort by, usually something like the date, the title etc.
direction
The direction of your sort order, either desc
for descending, or asc
for ascending.
method
The method takes an optional third parameter, the sort flag. The default is SORT_REGULAR
, but if you want to sort by numeric values, you can use SORT_NUMERIC
or other sort flags instead.
Sorting by a single field
Probably the use case most often needed is simple sorting of blog articles by date in reversed order, so that the most recent article appears first in the list:
Here, we pass two parameters to the sort()
method: the field we want to use for sorting (date
), and the sort order, here desc
. If you don't pass a sort order parameter, the default is ascending order.
An alternative would be skip the second parameter and use Kirby's flip()
method instead to achieve exactly the same as above:
Sorting by multiple fields
Sometimes, we don't want to limit sorting to a single field. Let's assume we wanted to sort a list of books by the authors' last and first names:
Here, we have pass two sort fields with their sort order as parameters. Authors will now be sorted by lastname first, then by firstname. You can add more criteria to sort by if necessary.
Sorting structure field entries
The same sorting methods outlined above can also be used with structure field entries - if you use the toStructure()
method.
An example: Suppose we have defined a structure field with three fields in our events blueprint:
Let's fetch the events, sort them by date and loop through them to output their content.
If you use yaml()
to create an array of events instead of a collection, and you want to sort that array, you can use the A::sort()
method from the toolkit, or check out the different ways to sort arrays in the PHP manual.
Custom sorting
Let's look at a sorting scenario that is beyond the usual sorting possibilities. Consider a structure field like this:
Now, instead of numbers, our sizes field contains sizes like S, M, L, XL, XXL
etc. Obviously, we cannot sort them alphabetically or otherwise, because they have no inherent order. So, what can we do? The solution here is to map a sorting value to every real value using the map()
method.
Of course, we can write all that stuff a bit shorter:
The map()
method is really useful for all types of scenarios, so keep it in mind for next time you come across a problem that you can't solve with a simple sort.
Sorting with Page Models
We cannot only use fields that exist in our content files for sorting. In fact, we can use all the methods the different collection classes (pages, files, etc.) provide (and that make sense to sort by). For example, you can sort by the template that is used by a page or file, if that makes sense for your use case. Or you can sort by a custom page model.
Let's assume for a moment that we wanted to sort our project pages by the number of images they have. Kirby doesn't have a native method that counts our images. We could now use the map()
method as outlined above, but we want to have some more fun and do something different now and create a Page Model with a method that returns the number of images.
The page model
I won't go into details with Page Models here. You can read more about how to create them in the docs
Now we can use this method to sort by:
Sorting files
Sorting files works just like with pages. We can sort by any file meta data field, or using built-in methods like modified()
, filename()
etc.
Some examples:
Note that the default sorting order of files is according to their order in the file system.
Sorting users
Users can also be sorted by any field in their profile or by inherent properties like role, language etc.
Some examples:
For files and users (and all the other stuff we can sort) we could also go to extremes, but let's keep it dry and finish here.