1

I have a Jinja2 template page which contains two separate {% for %} loops. If neither of these loops contain any items, I want the page to redirect.

I'm trying to do something like this (pseudo-code):

loop1 = loop.length (in first loop)
loop2 = loop.length (in second loop)

if loop1 + loop2 == 0: redirect # (outside both loops)

Is this even possible? Is there a way to make the loop.length variables available outside their respective loops?

Sean Vieira
  • 155,703
  • 32
  • 311
  • 293
DsDyer
  • 83
  • 6
  • err.. the redirect needs to come from the server and nothing to do with templates. – Jon Clements Jul 30 '12 at 19:46
  • try *first loop* `{% set i = loop.counter0 %}` *second loop* `{% set j = loop.counter0 %}` *condition* `{% if i+j equals 0 %}` – T I Jul 30 '12 at 19:46
  • That's what I tried first, but i and j don't exist outside their respective loops. – DsDyer Jul 30 '12 at 21:01
  • Each loop puts a div on the page each time it iterates, and these divs share a class, text, etc that is found nowhere else. Is there a way to simply, after both loops have run, say, "if this class or text does not exist on the page, redirect" ? – DsDyer Jul 30 '12 at 21:04

4 Answers4

0

You can check your lists for truth, empty lists are false in Jinja2.

{% if things %}
    {% for thing in things %} .... {% endfor %}
{% else %}
    <!-- redirect here -->
{% endif %}
John Gaines Jr.
  • 11,174
  • 1
  • 25
  • 25
  • The problem here is that I'm filtering the for condition, so it's actually {% for thing in things if not thing.attribute %} So how do I test if "things if not thing.attribute" is true? – DsDyer Jul 30 '12 at 22:21
0

The simple answer is "no": You can't re-direct using a template -- it should be in the view logic of the controller/server.

Although technically one can, but not doing anyone any favours.

Jon Clements
  • 138,671
  • 33
  • 247
  • 280
  • I realize that, but in this case I have no choice, the project (hopefully) won't require this for very long, and it was decided that doing it this way will be easier than changing things on the backend. – DsDyer Jul 30 '12 at 20:11
  • then you just proxy re-direct rules in the middle -- sounds like a horrible way to do so though – Jon Clements Jul 30 '12 at 20:17
  • @DsDyer: then you should ask the person who decided it was easy to write the code, and disprove everyone who asserts that it's not, in fact, easy. – Wooble Jul 30 '12 at 21:27
0

Assuming both things are lists, you can do this:

{% set all_things = thing1 + thing2 %}
{% if all_things %}
    {# There is more than one thing in the two lists #}
{% else %}
    {# redirect #}

That being said, this is not something that belongs at the template level - you are generating another list containing all of the things in thing1 and thing2 every time you hit the page, which will cost in terms of resources. You are putting application logic in the template level, which will not be maintainable. And finally, you are papering over the larger problem - that making changes to the back end code is costly. (Please understand that "you" in all these cases is the generic "you" - as in "the company you work for").

You (specifically) should raise these issues with those who are asking you to implement this hack and try to change the direction that this tool / product / company is taking before it becomes a piece of FrankenCode.

Good luck!

Sean Vieira
  • 155,703
  • 32
  • 311
  • 293
0

You could check the length things object(the object you are looping through) by using the length filter:

{{things|length}}

Now to answer your question. lets assume the objects you loop through is named t1 and t2, you could do:

{% if t1 | length == 0 and t2 | length == 0 %}
 //use javascript to redirect(assuming you have the link)
{% endif %}

You could do this in your JavaScript block. I do not know if this is the most efficient way to do it, but, it should work.

I am posting this answer, because there is no up-voted or accepted answer to this question.
I do Hope this helps.

Community
  • 1
  • 1
Renier
  • 1,523
  • 4
  • 32
  • 60