8👍
There are basically two approaches here:
- trying to construct a list, one way or another, and pass it to
my_tag
; or - change
my_tag
such that passing a list is more convenient.
Constructing lists
Django templates offer ways to construct a list, although most of these are rather limited.
Using the make_list
template filter
Django for example introduces a make_list
template filter [Django-doc] that takes an iterable, and converts it to a list of the items. For example we can use the template filter with:
{% my_tag paramA='asdf' paramB='fdsa' listparams='XY'|make_list %}
But there are two potential problems with this: (1) for a string it iterates over the characters, so the elements will all be 1-character strings, and (2) you can not construct lists that contain integers, etc. unless you already have a collection-like object, but this would basically make the make_list
useless.
Using .split()
We can solve the problem that it only takes 1-character strings, by performing a call to .split()
, this works only for strings (unless the type of the variable also supports a .split()
function), so we can solve the problem with mulit-char parts with:
{% my_tag paramA='asdf' paramB='fdsa' listparams='XY Z'.split %}
Implement a custom variadic tag to construct lists
We can also define a variadic tag, that first construct a list. We do this by implementing a custom tag:
# app/templatetags/create_list.py
from django import template
register = template.Library()
@register.simple_tag
def create_list(*args):
return args
We can then use two steps to pass a list:
{% load create_list %}
{% create_list 'X' 'Y' as mylist %}
{% my_tag paramA='asdf' paramB='fdsa' listparams=mylist %}
Changing my_tag
Perhaps a clean way could be to make use of positional parameters here to obtain the list. A function in Python has two types of parameters: positional ones (the ones passed without the name of the parameter), and named ones (the ones with key=...
).
We can thus use the positional ones here for the list, and thus call the tag with:
{% my_tag 'X' 'Y' paramA='asdf' paramB='fdsa' %}
In case we do not mention any positional parameters, the list is thus considered empty. We can pass an arbitrary number of parameters.
We can for example implement the tag as:
# app/templatetags/my_tag.py
from django import template
register = template.Library()
@register.simple_tag
def my_tag(*listparams, paramA=None, paramB=None):
# ... processing
return None
A potential problem with this approach is that we can only perform this “trick” once, in the sense that we can not define two separate such *arg
s. We can of course aim to split the *args
into two lists, but this can be tricky.