From b7e75b8ea7222d59c7c7c9f1b17d8d6da71d0b12 Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Mon, 24 Jan 2011 01:05:47 +0100 Subject: [PATCH] sort now also accepts an attribute --- CHANGES | 1 + jinja2/filters.py | 20 +++++++++++++++++++- jinja2/testsuite/filters.py | 9 +++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index a410c9e..7cda7b2 100644 --- a/CHANGES +++ b/CHANGES @@ -28,6 +28,7 @@ Version 2.6 incompatible change. The argument to the filter previously was the optional starting index which defaultes to zero. This now became the second argument to the function because it's rarely used. +- like sum, sort now also makes it possible to order items by attribute. Version 2.5.5 ------------- diff --git a/jinja2/filters.py b/jinja2/filters.py index 82f0153..a51d25b 100644 --- a/jinja2/filters.py +++ b/jinja2/filters.py @@ -191,7 +191,9 @@ def do_dictsort(value, case_sensitive=False, by='key'): return sorted(value.items(), key=sort_func) -def do_sort(value, reverse=False, case_sensitive=False): +@environmentfilter +def do_sort(environment, value, reverse=False, case_sensitive=False, + attribute=None): """Sort an iterable. Per default it sorts ascending, if you pass it true as first argument it will reverse the sorting. @@ -204,6 +206,18 @@ def do_sort(value, reverse=False, case_sensitive=False): {% for item in iterable|sort %} ... {% endfor %} + + It is also possible to sort by an attribute (for example to sort + by the date of an object) by specifying the `attribute` parameter: + + .. sourcecode:: jinja + + {% for item in iterable|sort(attribute='date') %} + ... + {% endfor %} + + .. versionchanged:: 2.6 + The `attribute` parameter was added. """ if not case_sensitive: def sort_func(item): @@ -212,6 +226,10 @@ def do_sort(value, reverse=False, case_sensitive=False): return item else: sort_func = None + if attribute is not None: + getter = make_attrgetter(environment, attribute) + def sort_func(item, processor=sort_func or (lambda x: x)): + return processor(getter(item)) return sorted(value, key=sort_func, reverse=reverse) diff --git a/jinja2/testsuite/filters.py b/jinja2/testsuite/filters.py index 6331d76..64cd0a9 100644 --- a/jinja2/testsuite/filters.py +++ b/jinja2/testsuite/filters.py @@ -257,6 +257,15 @@ class FilterTestCase(JinjaTestCase): tmpl = env.from_string('''{{ ['foo', 'Bar', 'blah']|sort }}''') assert tmpl.render() == "['Bar', 'blah', 'foo']" + def test_sort4(self): + class Magic(object): + def __init__(self, value): + self.value = value + def __unicode__(self): + return unicode(self.value) + tmpl = env.from_string('''{{ items|sort(attribute='value')|join }}''') + assert tmpl.render(items=map(Magic, [3, 2, 4, 1])) == '1234' + def test_groupby(self): tmpl = env.from_string(''' {%- for grouper, list in [{'foo': 1, 'bar': 2}, -- 2.26.2