Can't close div - if-statement

So for some kind of reason this small script gives a small error on the frontend (it doesnt give an error in the backend). So below I have stated 3 optioncolors. Alle work fine in the frontend, but if you are on the productpage of the last stated color (in this case Green), the URL given to this div won't close after the div but it will continue on the divs below. So every div below will have that same URL instead of only the div it should be. This error doesnt occur wit the 2 other colors, so only with the last color in the script. Any idea whats going on?
{% if product.title contains "Circle" and product.type == "T-shirts" %}
<a href="/products/black-circle-t-shirt">
{% if product.title contains "Black" %}<span class="black highlightcolor"></span>
{% else %}<span class="black"></span></a>{% endif %}
<a href="/products/orange-circle-t-shirt">
{% if product.title contains "Orange" %}<span class="orange highlightcolor"></span>
{% else %}<span class="orange"></span></a>{% endif %}
<a href="/products/green-circle-t-shirt">
{% if product.title contains "Green" %}<span class="green highlightcolor"></span>
{% else %}<span class="green"></span></a>{% endif %}
{% endif %}

Currently you're opening the <a> tags in all cases, but only closing them inside an else block -- meaning most of the time you'll wind up with mismatched tags.
Move all three of the closing </a> outside the conditional:
<a href="/products/black-circle-t-shirt">
{% if product.title contains "Black" %}
<span class="black highlightcolor"></span>
{% else %}
<span class="black"></span>
{% endif %}
</a>

Related

Django template - for loop and then if statement

I have this loop:
<div class="product-gallery-preview order-sm-2">
{% for images in Artikel.productimages_set.all %}
{% if images.Position == 1 %}
<div class="product-gallery-preview-item active" id="gallery{{ images.Position }}">
{% else %}
<div class="product-gallery-preview-item" id="gallery{{ images.Position }}">
the problem is that all div classes are active I think because it's true for the first picture which is found.
Is it possible to go in the loop check all pictures if it is in Position 1 and just output the div box I tried to print?
You can use forloop.counter...
{% if forloop.counter == 1 %}
<div class="product-gallery-preview-item active" id="gallery{{ images.Position }}">
{% else %}
....
{% endif %}

Getting the last for loop iteration of condition in django templates

I wish to add the class rounded-t-lg shadowon the first iteration inside the if statement, and rounded-b-lg shadow on the last iteration. I have the following code:
{% for note in notes %}
{% if note.is_sticky %}
<div class="flex items-center">
<div class="{% if forloop.first %} rounded-t-lg shadow {% elif forloop.last %} rounded-b-lg shadow {% endif %}">
<!-- code -->
</div>
</div>
</div>
{% endif %}
{% endfor %}
The problem that I'm running into is that forloop.last applies to the last iteration in general, and not the last iteration in the condition. So if I have three objects, where two is sticky, and the last one is not, the class will be applied to the one that is not, since its the last in "line".
How can I apply a class to the last iteration within the is_sticky condition, regardless of the objects that do not meet the condition?
Ideally you should filter the notes list in your view, so it only contains those where is_sticky == True. Depending on your queryset you may just need to add:
.filter(is_sticky=True)
I also think you might need to be careful of the case when there is only 1 element in notes. I guess you want it to be rounded top and bottom, so you need 2 separate if tests, rather than an elsif.
{% for note in notes %}
<div class="flex items-center">
<div class="{% if forloop.first %} rounded-t-lg shadow{% endif %}{% if forloop.last %} rounded-b-lg shadow{% endif %}">
<!-- code -->
</div>
</div>
{% endfor %}
This should work:
{% for note in notes %}
{% if forloop.first %}
{% if note.is_sticky %}
<div class="flex items-center">
<div class="rounded-t-lg shadow">
<!-- code -->
</div>
</div>
</div>
{% endif %}
{% elif forloop.last %}
{% if note.is_sticky %}
<div class="flex items-center">
<div class="rounded-b-lg shadow">
<!-- code -->
</div>
</div>
</div>
{% endif %}
{% endif %}
{% endfor %}

ListView with alternate background image

This code doesn't work! I want to show an red image and then a blue image. If I have 5 object the the list should be: Red Blue Red Blue Red.
I want to do this with 2 colours. I tried the following code:
{% extends './base.html' %}
{% block content %}
{% for object in object_list %}
{% if forloop.counter0 % 2 ==0 }
<img src="img/red.jpg">
<p> {{object.title}} </p>
{% else %}
<img src="img/blue.jpg">
<p> {{object.title}} </p>
{% endif %}
{% endfor %}
{% endblock content %}
You can't use % in templates. Django has a divisibleby filter you could use.
However, it would be better to use the cycle tag:
{% for object in object_list %}
<img src="{% cycle 'image/red.jpg' 'image/blue.jpg' %}">
<p>{{object.title}}</p>
{% endfor %}
Django templates don't have modulus %, they use divisibleby:2
So your code would be this instead:
{% if forloop.counter0|divisibleby:2 %}

Django TemplateError when using if...else block inside for loop

I have the following as part of my django template:
<nav>
<ul class="pagination">
{% if page.has_previous %}
<li>
<a href="{% url 'main:stream_detail' stream_id=stream.id %}?p={{page.next_page_number}}" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
{% else %}
<li class="disabled" aria-label="previous"><span aria-hidden="true">«</span></li>
{% endif %}
{% for i in paginator.page_range %}
(% if i == page.number %}
<li class="active">{{i}} <span class="sr-only">(current)</span></li>
{% else %}
<li>{{i}}</li>
{% endif %}
{% endfor %}
{% if page.has_next %}
<li>
<a href="{% url 'main:stream_detail' stream_id=stream.id %}?p={{page.next_page_number}}" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
{% else %}
<li class="disabled" aria-label="next"><span aria-hidden="true">»</span></li>
{% endif %}
</ul>
</nav>
And I'm getting the following exception:
Invalid block tag on line 26: 'else', expected 'empty' or 'endfor'. Did you forget to register or load this tag?
Line 26 corresponds to the {% else %} clause inside the {% for %} loop. As fas as I can tell, this else clause correctly matches up with the if statement, but the template parser seems to expect a clause to match the for loop there.
You have a syntax error with the if tag in the for loop:
(% if
...should be
{% if
You used '(' instead of '{' on line (% if i == page.number %}

django - Invalid block tag: 'add_pinned_status', expected 'else' or 'endif'

I get the following error when serving my django application using Nginx+FastCGI
Invalid block tag: 'add_pinned_status', expected 'else' or 'endif'
Oddly, the site works just fine when I'm serving using the Django development server. It also works with Nginx most of the time, but the error randomly appears and reappears with refreshes. Any idea what the problem could be?
EDIT: Here's the code, just to clarify that there's NO hanging if statement.
{% extends 'master.html'%}
{% load thumbnail %}
{% load tags %}
{% block 'title' %}
{{ title }}
{% endblock %}
{% block 'content' %}
<div id="feed" class="content">
{% for book in books.object_list %}
<div class="book_preview">
<div class="thumbnail">
<a href="/book/{{ book.id }}/{{ book.get_slug }}/">
{% if book.cover_image %}
{% thumbnail book.cover_image "120" as im %}
<img src="{{ im.url }}" alt="Python for Software Design"/>
{% endthumbnail %}
{% else %}
<img src="{{ STATIC_URL }}default_thumb.jpg" alt="Python for Software Design"/>
{% endif %}
</a>
</div>
<div class="book_details">
<h2 class="book_title">
<a class="book_profile_link" href="/book/{{ book.id }}/{{ book.get_slug }}/">{{ book.title }}</a>
{% if user != book.uploader %}
<a class="shelf_adder {% add_pinned_status request book.pk %}" href="/shelf/{{ book.id }}/toggle/?next={{ request.get_full_path }}" title="Toggle shelf status"></a>
{% endif %}
</h2>
<h3 class="book_subtitle">
{% if book.subtitle %}
{{ book.subtitle }}
{% else %}
<a href='/book/{{book.id}}/edit/#subtitle'>Provide subtitle</a>
{% endif %}
</h3>
<h3 class="book_authors"> by {{ book.author.filter|join:", " }}</h3>
<div class="book_description">
{% if book.description %}
<p>
{{ book.description|truncatewords:25 }}
</p>
{% else %}
<p class="message">No description available. Create one.</p>
{% endif %}
</div>
<div class="book_links">
<a href="/book/{{ book.id }}/{{ book.get_slug }}/" class="book_profile_link" title="Book profile">
Book profile
</a>
<a href="http://{{ book.homepage }}" class="book_website_link" title="Book website" target="_blank">
Book website
</a>
</div>
<p>Points: {{ book.shelf_additions }}</p>
<div class="book_tags">
{% if book.topics.all %}
{% for topic in book.topics.filter %}
{{ topic }}
{% endfor %}
{% else %}
<a href="/book/{{ book.id }}/edit/#topics" title='Click to add'>no topics added☹</a>
{% endif %}
</div>
</div>
<div style="clear: both;"></div>
</div>
{% endfor %}
<div class="pagination">
{% if books.has_previous %}
previous
{% endif %}
<span class="current">
Page {{ books.number }} of {{ books.paginator.num_pages }}
</span>
{% if books.has_next %}
next
{% endif %}
</div>
</div>
{% endblock %}
The problem starts on the line after the if user != book.uploader statement, which as you can see is terminated with the appropriate endif. I suspect it may be some sort of timeout but I'm not entirely sure. Keep in mind, it works sometimes but randomly stops when using Nginx. It works flawlessly with the dev server.
Django gives that error when you have an unclosed templatetag. In this case an {% if ... %} templatetag.
As to why it only happens in certain scenarios, it might be inside a conditional tag itself, so it's not always processed, but I think Django processes the whole template despite what's going on conditionally or not. It might also be possible that there was some mistake in updating your production site and it's using a different/older version than your development site.
Regardless, the error is the error. Find the unclosed templatetag, and you'll solve it across the board.
UPDATE: The alternative is that the add_pinned_sites templatetag is undefined. Assuming it is in fact loaded in {% load tags %}, make sure that that templatetag library is available in all running environments, i.e. it literally exists on the server. If it is in fact there, make sure you completely reload your Nginx+FastCGI environment, or just reboot the server to be completely sure.
Is "tags" the actual name of the tag library that holds add_pinned_sites? Might be worth changing it to a clearer name-- just wondering if it's possible you're seeing import collisions between that and another tag library (like Django's built-in tags).