Passing a list to a DTL tag

I was attempting to pass a list of request parameter names into a custom tag, so that I could retain GET parameters from one form when submitting the other form.

Form 1.

<form class="border border-secondary-subtle rounded-3 p-3 mb-3" method="get" novalidate>
  <h3 class="fw-semibold mb-3">Pretraga</h3>

  <div class="row gy-3 mb-3">
    <div class="col-6 col-md-12">
      <div class="form-floating">
        {{ filter.form.grad }}
        <label for="grad">Grad</label>
      </div>
    </div>

    <div class="col-6 col-md-12">
      <div class="form-floating">
        {{ filter.form.broj_soba }}
        <label for="broj_soba">Broj soba</label>
      </div>
    </div>

    <div class="col-6 col-md-12">
      <div class="input-group">
        <div class="form-floating">
          {{ filter.form.m2_od }}
          <label for="m2_od">Površina od</label>
        </div>

        <div class="form-floating">
          {{ filter.form.m2_do }}
          <label for="m2_do">Površina do</label>
        </div>
      </div>
    </div>

    <div class="col-6 col-md-12">
      <div class="input-group">
        <div class="form-floating">
          {{ filter.form.cena_od }}
          <label for="cena_od">Cena od</label>
        </div>

        <div class="form-floating">
          {{ filter.form.cena_do }}
          <label for="cena_do">Cena do</label>
        </div>
      </div>
    </div>
  </div>

  <input class="btn btn-primary fw-semibold" type="submit" value="Pretražite">
</form>

Result: ?grad=&broj_soba=&m2_od=&m2_do=&cena_od=&cena_do=

Form 2.

{% load listing_extras %}

{# Sort select #}
<form class="w-50 mb-3" method="get">
  {# Checks if GET parameters from previous form are present and submits the hidden forms if present. #}
  {% all2 request ["grad", "broj_soba", "m2_od", "m2_do", "cena_od", "cena_do"] as all %}
  {% if all %}
    <input type="hidden" name="grad" value="{{ request.GET.grad }}">
    <input type="hidden" name="broj_soba" value="{{ request.GET.broj_soba }}">
    <input type="hidden" name="m2_od" value="{{ request.GET.m2_od }}">
    <input type="hidden" name="m2_do" value="{{ request.GET.m2_do }}">
    <input type="hidden" name="cena_od" value="{{ request.GET.cena_od }}">
    <input type="hidden" name="cena_do" value="{{ request.GET.cena_do }}">
  {% endif %}

  <select class="form-select" name="redosled" onchange="this.form.submit()">
    {% for ot in orders %}
      <option value="{{ ot.0 }}" {% if ot.0 == request.GET.redosled %}selected{% endif %}>
        {{ ot.1 }}
      </option>
    {% endfor %}
  </select>
</form>

Expected result: ?grad=&broj_soba=&m2_od=&m2_do=&cena_od=&cena_do=&redosled=popularniji

The template tag that checks if parameters are present in the request. It didn’t work, because it caused syntax errors.

@register.simple_tag
def all2(request: HttpRequest, l: list):
    return all([param in request.GET for param in l])

So I came up with another way.

@register.simple_tag
def all2(request: HttpRequest):
    params = ["grad", "broj_soba", "m2_od", "m2_do", "cena_od", "cena_do"]
    return all([param in request.GET for param in params])
{% all2 request as all %}

Sad that it’s impossible passing lists into template tags in DTL.

Sure you can. You just don’t use the “list” notation as a literal.

Aside from being able to pass a list as a context variable, you’ve got a couple different ways to work it directly.

Example:

becomes:
{% all2 request "grad", "broj_soba", "m2_od", "m2_do", "cena_od", "cena_do" as all %}

And

becomes:

@register.simple_tag
def all2(request, *l):
    return all([param in request.GET for param in l])

Or, if you’re only passing literal strings, you could also pass them as a single string and use the “split” method on it.

Or, my personal preference is actually what you use as your alternative - don’t pass it from the template. My opinion is that it belongs in the tag - it’s “business logic” or a “business definition” that doesn’t belong in the template itself as a list of literal strings.

If it’s always the same list, I’d maintain that it belongs in the view, tag or filter. If it’s a variable list that depends upon the situation, then I’d say it belongs in the context as a variable.