publik: use list/add filters to create list from simple values (#81223)
gitea/publik-django-templatetags/pipeline/head This commit looks good
Details
gitea/publik-django-templatetags/pipeline/head This commit looks good
Details
This commit is contained in:
parent
6e9d0a8b63
commit
063f03c491
|
@ -14,6 +14,7 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import collections
|
||||
import datetime
|
||||
import math
|
||||
from decimal import Decimal
|
||||
|
@ -124,19 +125,35 @@ def decimal(value, arg=None):
|
|||
def add(term1, term2):
|
||||
'''replace the "add" native django filter'''
|
||||
|
||||
# consider None content as the empty string
|
||||
if term1 is None:
|
||||
term1 = ''
|
||||
if term2 is None:
|
||||
term2 = ''
|
||||
term1_decimal = parse_decimal(term1, default=None)
|
||||
term2_decimal = parse_decimal(term2, default=None)
|
||||
|
||||
if term1_decimal is not None and term2_decimal is not None:
|
||||
return term1_decimal + term2_decimal
|
||||
if term1 == '' and term2_decimal is not None:
|
||||
return term2_decimal
|
||||
if term2 == '' and term1_decimal is not None:
|
||||
return term1_decimal
|
||||
# return available number if the other term is the empty string
|
||||
if term1 == '':
|
||||
try:
|
||||
return parse_decimal(term2, do_raise=True)
|
||||
except (ArithmeticError, TypeError):
|
||||
pass
|
||||
if term2 == '':
|
||||
try:
|
||||
return parse_decimal(term1, do_raise=True)
|
||||
except (ArithmeticError, TypeError):
|
||||
pass
|
||||
|
||||
# compute addition if both terms are numbers
|
||||
try:
|
||||
return parse_decimal(term1, do_raise=True) + parse_decimal(term2, do_raise=True)
|
||||
except (ArithmeticError, TypeError, ValueError):
|
||||
pass
|
||||
|
||||
# append to term1 if term1 is a list and not term2
|
||||
if isinstance(term1, list) and not isinstance(term2, list):
|
||||
return list(term1) + [term2]
|
||||
|
||||
# fallback to django add filter
|
||||
return defaultfilters.add(term1, term2)
|
||||
|
||||
|
||||
|
@ -224,3 +241,12 @@ def duration(value, arg='short'):
|
|||
except (TypeError, ValueError):
|
||||
return ''
|
||||
return utils.seconds2humanduration(int(value.total_seconds()), short=bool(arg != 'long'))
|
||||
|
||||
|
||||
@register.filter(name='list')
|
||||
def list_(value):
|
||||
# turn a generator into a list
|
||||
if isinstance(value, collections.abc.Iterable) and not isinstance(value, (collections.abc.Mapping, str)):
|
||||
return list(value)
|
||||
else:
|
||||
return [value]
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import html
|
||||
|
||||
from django.template import Context, Template
|
||||
|
||||
|
||||
|
@ -409,3 +411,28 @@ def test_duration():
|
|||
Template('{{ value|duration:"long" }}').render(context)
|
||||
== '3 years, 1 month, 30 days, 15 hours and 46 minutes'
|
||||
)
|
||||
|
||||
|
||||
def test_convert_as_list():
|
||||
tmpl = Template('{{ foo|list|first }}')
|
||||
assert tmpl.render(Context({'foo': ['foo']})) == 'foo'
|
||||
|
||||
def list_generator():
|
||||
yield from range(5)
|
||||
|
||||
assert tmpl.render(Context({'foo': list_generator})) == '0'
|
||||
|
||||
def list_range():
|
||||
return range(5)
|
||||
|
||||
assert tmpl.render(Context({'foo': list_range})) == '0'
|
||||
|
||||
|
||||
def test_convert_as_list_with_add():
|
||||
tmpl = Template('{{ foo|list|add:bar|join:", " }}')
|
||||
assert tmpl.render(Context({'foo': [1, 2], 'bar': ['a', 'b']})) == '1, 2, a, b'
|
||||
assert tmpl.render(Context({'foo': [1, 2], 'bar': 'ab'})) == '1, 2, ab'
|
||||
assert tmpl.render(Context({'foo': 12, 'bar': ['a', 'b']})) == '12, a, b'
|
||||
assert tmpl.render(Context({'foo': 12, 'bar': 'ab'})) == '12, ab'
|
||||
assert html.unescape(tmpl.render(Context({'foo': [1, 2], 'bar': {'a': 'b'}}))) == "1, 2, {'a': 'b'}"
|
||||
assert html.unescape(tmpl.render(Context({'foo': {'a': 'b'}, 'bar': ['a', 'b']}))) == "{'a': 'b'}, a, b"
|
||||
|
|
Loading…
Reference in New Issue