Modify ↓
Opened 16 months ago
Closed 14 months ago
#13773 closed defect (fixed)
Custom max and min filters for Jinja2 templates accept an iterable object
| Reported by: | Jun Omae | Owned by: | Jun Omae |
|---|---|---|---|
| Priority: | normal | Milestone: | 1.6.1 |
| Component: | rendering | Version: | 1.4 |
| Severity: | normal | Keywords: | |
| Cc: | Branch: | ||
| Release Notes: |
|
||
| API Changes: | |||
| Internal Changes: | |||
Description
Trac core provides custom max and min filters, however the same filters have been added in Jinja2 3.0. The max and min filters in Trac don't accept an iterable object but the same filters in Jinja2 accept an iterable object.
I just encountered this error, I spent 2 days.
>>> tmpl = chrome.jenv.from_string('${ data|map("upper")|max(default="?") }')
>>> tmpl.render(data=['Aaa', 'Bbb', 'ccc'])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/jun66j5/venv/py311/lib/python3.11/site-packages/jinja2/environment.py", line 1304, in render
self.environment.handle_exception()
File "/home/jun66j5/venv/py311/lib/python3.11/site-packages/jinja2/environment.py", line 939, in handle_exception
raise rewrite_traceback_stack(source=source)
File "<template>", line 1, in top-level template code
File "/home/jun66j5/venv/trac/1.6/lib/python3.11/site-packages/trac/util/presentation.py", line 141, in max_filter
if len(seq):
^^^^^^^^
TypeError: object of type 'generator' has no len()
>>> from jinja2 import Environment, BaseLoader
>>> jenv = Environment(loader=BaseLoader())
>>> tmpl = jenv.from_string('{{ data|map("upper")|max }}')
>>> tmpl.render(data=['Aaa', 'Bbb', 'ccc'])
'CCC'
Work around is to apply list filter before max.
-${ data|map("upper")|max(default="?") } +${ data|map("upper")|list|max(default="?") }
Patch:
-
trac/util/presentation.py
diff --git a/trac/util/presentation.py b/trac/util/presentation.py index 196a6c2b0..fc561ffb7 100644
a b def htmlattr_filter(_eval_ctx, d, autospace=True): 138 138 139 139 def max_filter(seq, default=None): 140 140 """Returns the max value from the sequence.""" 141 if len(seq): 142 return max(seq) 143 return default 141 return max(seq, default=default) 144 142 145 143 def min_filter(seq, default=None): 146 144 """Returns the min value from the sequence.""" 147 if len(seq): 148 return min(seq) 149 return default 145 return min(seq, default=default) 150 146 151 147 152 148 def trim_filter(value, what=None):
Attachments (0)
Change History (2)
comment:1 by , 14 months ago
comment:2 by , 14 months ago
| Release Notes: | modified (diff) |
|---|---|
| Resolution: | → fixed |
| Status: | assigned → closed |
| Type: | enhancement → defect |
| Version: | → 1.4 |
Note:
See TracTickets
for help on using tickets.



I noticed the
minfilter is never used due to a typo….trac/util/presentation.py
x=min_filter,