'Twig sort array of objects by field
I have entity with fields:
User
- name
- lastname
- age
and few more. Im sending to Twig array with objects user.
In twig display users in table:
{% for user in users %}
<td>{{ user.name }}<td> <td>{{ user.lastname}}<td> <td>{{ user.age}}<td>
{% endfor %}
How can I sort users via name or lastname etc. in Twig. I want to create sortable table.
Solution 1:[1]
Starting with Twig 2.12 (released on October 5, 2019) you can use the sort filter with an arrow function in the arrow argument.
For example, to order by name:
{% for user in users|sort((a, b) => a.name <=> b.name) %}
<td>{{ user.name }}</td> <td>{{ user.lastname}}</td> <td>{{ user.age}}</td>
{% endfor %}
Twig docs: https://twig.symfony.com/doc/2.x/filters/sort.html
Solution 2:[2]
Yes, You can add custom filter:
{% for user in users|usort %}
...
{% endfor %}
and then add Extension/new filter to Twig:
new \Twig_SimpleFilter('usort', array($this, 'usortFilter'))
public function usortFilter($item){
usort($item, function ($item1, $item2) {
if ($item1['orderNo'] == $item2['orderNo']) return 0;
return $item1['orderNo'] < $item2['orderNo'] ? -1 : 1;
});
return $item;
}
Solution 3:[3]
Sorting in reverse order:
{% for user in users|sort|reverse %}
...
{% endfor %}
sort and revers are combinable.
Solution 4:[4]
I'm using Timber for Wordpress which still uses Twig 1+, so I couldn't use the arrow argument. I just created a filter like this using PHP’s usort function:
// sort an array of objects by parameter
$twig->addFilter( new Twig_SimpleFilter( 'sort_by_key',
function ( $array, $key, $order = 'asc', $type = 'string' ) {
usort( $array, function($a, $b) use ($key, $order, $type) {
$a = $a[$key]; $b = $b[$key];
if( $type === 'date' ) {
$a = strtotime( $a );
$b = strtotime( $b );
}
if( $a == $b ) {
return 0;
}
switch( $order ) {
case 'desc' : case 'DESC' :
return $a < $b ? 1 : -1;
break;
default :
return $a < $b ? -1 : 1;
}
} );
return $array;
}));
And then in my twig template:
{% set array = myArrayOfObjects | sort_by_key('date', 'desc', 'date') %}
Works well with the Advanced Custom Fields repeater field.
Solution 5:[5]
With new version twig you can sort by colonne
{% set fruits = [
{ name: 'Apples', quantity: 5 },
{ name: 'Oranges', quantity: 2 },
{ name: 'Grapes', quantity: 4 },] %}
{% for fruit in fruits|sort((a, b) => a.quantity <=> b.quantity)|column('name') %}
{{ fruit }}
{% endfor %}
Solution 6:[6]
You must do this in your model using an "Order by" clause. However, if you want to have a table that can be sorted dynamically, you should watch about the jQuery tablesorter plugin (or equivalent if you do not want to use jQuery).
Solution 7:[7]
For those working with Collections in Grav, you can simply do this:
{% for user in users.order("name", "asc") %}
...
{% endfor %}
Of course, name can be any property of the given object and asc can alternatively be desc.
This also works with dot-concatenated properties:
{% for child in page.children.order("page.headers.foo.bar", "desc") %}
Solution 8:[8]
Before Twig 2.12 It was not possible out of the box to order by specific field. Update your twig, or you could write a custom twig extension which does what you need. See @cgaldiolo and @unbreak answers.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | unbreak |
| Solution 3 | BenS. |
| Solution 4 | |
| Solution 5 | Lamri Djamal |
| Solution 6 | Devatoria |
| Solution 7 | |
| Solution 8 |
