How to debug strange artefacts in django template? - python

I'm using django template to render my hierarchical tree in a web page. In the process of rendering of a tree I see these strange whitespaces between nodes:
Here is my recursive template:
index.html:
<ul class="Container">
<li class="IsRoot">
<div class="Expand">
</div>
<div class="Content">
Содержание
</div>
</li>
{% include 'list.html' with data=list %}
</ul>
and list.html (as a recursive part):
<ul class="Container">
<li class="Node ExpandClosed">
<div class="Expand"></div>
<div class="Content">
<a href="/help/{{data.name}}">
{{data.content}}
</a>
</div>
{% for item in data.decendent %}
{% include 'list.html' with data=item %}
{% endfor %}
</li>
</ul>
How to debug what's the matter with this template and in what period of time it happens? As you can see, I don't generate any whitespaces in this template.

The white space is not the problem, and it is not causing the spaces in your rendered tree. The reason for that appears to be that you are nesting ul elements directly inside uls, which isn't strictly speaking valid: they should be inside lis.

Related

Changing the size of bootstrap cards in a Django project?

I'm working on a simple Django project with bootstrap. I have a set of cards being displayed on a page, and the cards are showing just fine (Don't mind the place holder images).
I've been reading the bootstrap docs about cards, but since I have less knowledge of CSS than I'd like, I can't figure out how to simply change the size of the cards so they are larger and stacked in rows instead of one column.
This is my HTML template for this page. It just uses a for-loop to go through my projects and make a card for each. You can see I have the title and text worked out, and the URL to 'See Details'.
{% extends "base.html" %}
{% load static %}
{% block page_content %}
<h1>Projects</h1>
<div class="row">
{% for project in projects %}
<div class="col-md-4">
<div class="card mb-2">
<img class="card-img-top" src="{% static project.image %}">
<div class="card-body">
<h5 class="card-title">{{ project.title }}</h5>
<p class="card-text">{{ project.description }}</p>
<a href="{% url 'project_detail' project.pk %}"
class="btn btn-primary">
See Details
</a>
</div>
</div>
</div>
{% endfor %}
</div>
{% endblock %}
The Base.html is just linking to the bootstrap and all the html for the top of the page. Hopefully the fix is a really simple addition to the template, but I haven't had much luck finding info.
You can use row to create grid row for each card object, and remove the col div.
{% extends "base.html" %}
{% load static %}
{% block page_content %}
<h1>Projects</h1>
{% for project in projects %}
<div class="row">
<div class="card mb-2">
<img class="card-img-top" src="{% static project.image %}">
<div class="card-body">
<h5 class="card-title">{{ project.title }}</h5>
<p class="card-text">{{ project.description }}</p>
<a href="{% url 'project_detail' project.pk %}"
class="btn btn-primary">
See Details
</a>
</div>
</div>
</div>
{% endfor %}
{% endblock %}

TemplateSyntaxError at endfor in jinja django coding

jinja2 is not recognizing {% endfor %} and runs into this error:
TemplateSyntaxError at endfor in jinja django coding
Below is the code snippet:
{% for dest in dests % }
<!-- Destination -->
<div class="destination item">
<div class="destination_image">
<img src="{{im}}/{{dest.img}}" alt="">
<div class="spec_offer text-center">Special Offer</div>
</div>
<div class="destination_content">
<div class="destination_title">{{dest.name}}</div>
<div class="destination_subtitle"><p>{{dest.desc}}</p></div>
<div class="destination_price">From ${{dest.price}}</div>
</div>
</div>
{% endfor %}
Here dest is a list which is displaying the content.
It is not recognizing the forloop because your jinja formatting is wrong.Cannot have space at start and end of percentage.Change to this{% for dest in dests %}.
when you are getting images for database you need .url at the end. So you code should look like <img src="{{dest.img.url}}" alt="">

How do I solve this TemplateSyntaxError in Django that says "Could not parse the remainder"

I am trying to render a block of HTML code repeatedly using for loop. But Django throws a TemplateSyntaxError when I reload my browser
<div class="carousel-item active">
{% for number in range(3) %}
<!--Slide {{ number + 1 }}-->
<div class="row">
{% for number in range(6) %}
<!--Slide 1 Col {{ number + 1 }}-->
<div class="col-lg-2">
<div class="card" style="width: 100%;">
<img class="card-img-top" src="..." alt="Card image cap">
<div class="card-body">
<h5 class="card-title">Card title</h5>
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
Go somewhere
</div>
</div>
</div>
{% endfor %}
</div>
{% endfor %}
</div>
I expected a repeated rendering of the blocks inside the for loop but got "TemplateSyntaxError at /
Could not parse the remainder: '(3)' from 'range(3)'" instead
Django does not allow to make function calls (with parameters) as well as subscripting in the templates. The rationale is that business logic should not be part of the template. You thus can pass the range(3) and range(6) object through the context to the template. The {{ number + 1 }} will not work either, since such operators are not supported either.
An alternative is using Jinja, which is a template engine that does allow to use such Python syntax in the templates.
Since the numbers are quite small, a third options is to use string literals instead:
<div class="carousel-item active">
{% for row in '123' %}
<!--Slide {{ row }}-->
<div class="row">
{% for col in '123456' %}
<!--Slide 1 Col {{ col }}-->
<div class="col-lg-2">
<div class="card" style="width: 100%;">
<img class="card-img-top" src="..." alt="Card image cap">
<div class="card-body">
<h5 class="card-title">Card title</h5>
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
Go somewhere
</div>
</div>
</div>
{% endfor %}
</div>
{% endfor %}
</div>

Any limitation on HTML <li>?

I have the following code with Python:
<div id="sidebar-wrapper" class="container-fluid" style="background-color: lightgray">
<nav id="spy" class="nav nav-pills navbar-stacked">
<ul class="sidebar-nav nav">
<li class="">
<a href="{% url 'PHIproduct' %}" data-scroll="" class="">
<span class="fa fa-anchor solo"><h3>Product List</h3></span>
</a>
<li class="">
{% for i in loop_times_product %}
<a href="{% url 'PHI' %}?id={{ i }}" data-scroll="" class="">
<span class="fa fa-anchor solo" id="{{ i }}">{{ i|safe }}</span>
</a>
{% endfor %}
<li class="">
{% for i in loop_times %}
<a href="{% url 'PHIc' %}?id={{ i }}" data-scroll="" class="">
<span class="fa fa-anchor solo" id="{{ i }}">{{i|safe}}</span>
</a> {% endfor %}
<li class="">
{% for i in loop_timesc %}
<a href="{% url 'button' %}?id={{ i }}" data-scroll="" class="">
<span class="fa fa-anchor solo" id="{{ i }}">{i|safe}}</span>
</a> {% endfor %}
</li>
</li>
</li>
</li>
</ul>
</nav>
</div>
The main purpose is to add following feature:
After I apply this code, when product A is clicked, the car and motor will not show, which means this part of code is not running:
<li class="">
{% for i in loop_timesc %}<span class="fa fa-anchor solo" id="{{ i }}">{{i|safe}}</span>
{% endfor %}
</li>
Is there any limitation on li code or am I writing the wrong code here? Can anyone help me look at this because I already spent 2 days trying to find the mistake here but have failed.
I didn't inspect your code in great detail, but one thing jumped out at me: you're nesting <li> elements directly inside each other. You can't do that; an <li> needs to be a direct child of an <ol> or <ul>.
Forget about Python for the moment and just look at a simple HTML example.
Invalid:
<ul>
<li>
One
<li>
One A
</li>
</li>
</ul>
Valid:
<ul>
<li>
One
<ul>
<li>
One A
</li>
</ul>
</li>
</ul>
There may be other problems in your code, but this is certainly one to fix.
Another tip: if you're working a suspected HTML issue like this where one of the problems may be that the generated HTML simply isn't valid, don't try to figure out everything from your Python template source code. Instead, do a View Source in the browser where you can see exactly what the browser sees.
In fact, you can do a Select All and Copy from the View Source window, and then paste into the W3C HTML Validator to see if the HTML is valid. If you're generating invalid HTML, all bets are off, so that is the first thing to check.
If you treat your server code (including templates) separately from the actual downloaded HTML that the browser sees, you'll have a much easier time debugging. The server generates HTML code; the browser parses and renders the HTML code that the server generated.

how to change batch argument dynamically in jinja template depending on device size

I have the below bootstrap panels, three col-xs-4 per row rendered in a jinja template, and it looks super nice on a desktop.
but when trying smaller devices it get ugly. so I want to know if there is a way to change the batch argument to 1 per row under a certain device size ?
or maybe there is a better approach, I'm very open as I'm very new to this :)
<div class="container-fluid">
{% for raceorganizers in res.keys() | batch(3, ' ') %}
<div class="row">
{% for raceorganizer in raceorganizers %}
<div class="col-xs-4">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">{{ raceorganizer.name }}<span
class="text-right pull-right flag-icon flag-icon-{{ raceorganizer.country_code }}"></span>
</h3>
</div>
<div class="panel-body panel-image">
<img class="panel-image-preview"
src="{{ url_for('static', filename='img/full/' + im ) }}" alt='{{ im }}'>
</div>
<div class="panel-footer">
{% for race in res[raceorganizer] %}
<ul class="list-unstyled">
<li>
<span class="glyphicon glyphicon-road"></span>
<span class="badge">{{ '{:.1f}'.format(race.distance_number) }}</span>
<span class="flaticon-mountain40"></span>
<span class="badge">{{ '{:.0f}'.format(race.elevation_number) if race.elevation_number is not none else '-' }}</span>
</li>
</ul>
{% endfor %}
</div>
</div>
</div>
{% endfor %}
</div>
{% endfor %}
</div>
If you look more closely at bootstrap's grid system, you could completely get rid of the batch call. If you play with different tiers of classes (col-xs for phones+, col-md for desktops+) on the same element, you will be able to get bootstrap to split the content into 3 columns on desktops and 1 on smaller screens.

Categories

Resources