I have a for loop in Twig. I'm trying to access different elements in a for loop so I can use them in different places on my website.
Let'say I have a template called 'images'. Inside that template I have a for loop like so:
{% for image in images %}
<div>
<img src="{{ image | url_image }}" width="100" height="100" />
</div>
{% endfor %}
In a different template I'm trying to include this 'images' template. So what I have is this:
{% include 'images.html' %}
The problem I'm facing right now is that I only want the second element from the for loop in the images.html template. How do you do that?
So I want something like this:
<div>
{% include 'images.html' with {'second element'} only %}
</div>
Does anyone know what the best approach is or how do you do that? I'm pretty new to Twig as you can see ;)
You almost already found your answer!
Use the for with condition syntax:
{% for key,image in images if key==elementNumber %}
<div>
<img src="{{ image | url_image }}" width="100" height="100" />
</div>
{% endfor %}
And call you template with the parameter's value you need (keeping in mind that key starts at 0, so the example bellow will give you the second element):
<div>
{% include 'images.html' with {elementNumber: 1} %}
</div>
This syntax is useful if you want to do some "elaborated" things like if key<elementNumber
But if you need only one element at a time, this might be better, instead of the for loop:
<div>
<img src="{{ images[elementNumber] | url_image }}" width="100" height="100" />
</div>
Related
In Django I am trying to loop through all of the children of my Todo model. But whenever I try to run it, it gives me an AttributeError that says "Manager isn't accessible via Todo instances". My code looks like this:
{% extends 'base.html' %}
{% block content %}
<h3>Tasks</h3>
{% for t in model.objects.all %} <!-- Error -->
<p>{{t.name}}</p>
{% endfor %}
{% endblock %}
{% block options %}
<li class="bg-light py-3 w-100 px-4 rounded text-nowrap fs-4">
<button class="text-decoration-none text-dark">Save</button>
</li>
{% endblock %}
I tried to just put the model in the context, and then I got an error in the HTML, so I figured out that it happened when I tried to reference 'model.objects.all'.
Inside of your view you need to specify what django should pass to the template. It does not serve the entire Database; therefore queries like in model.objects.all inside of your templates are not allowed.
Specify the queryset inside your views.py:
def todo_view(request):
context = {}
context['my_todos'] = my_todo_model.objects.all()
context['most_important_todo'] = my_todo_model.objects.get(pk=1)
# put your own logic inside the `.get` method above
return render(request, 'my_template.html' context)
And then access it inside of your template like so:
{% for t in my_todos %}
<p>{{ t.name }}</p>
{% endfor %}
{{ most_important_todo.name }}
Because we put a queryset inside of my_todos we can loop over it in the template. most_important_todo ist just a single object passed to the template, so we can access its properties (e.g. the name) directly.
Let me know how it goes
I am trying to loop over a nested list in my posts font matter and display an associated image (using svg) for each nested item
post front matter:
---
layout: post
title: title of this post
spec:
- name: tee
- name: mobile
---
using a for loop in my post.html file
<div>
<h4>specs</h4>
{% for item in page.spec %}
<svg class='spec-icon'><use xlink:href="#icons_{{item.name}}"/</svg>
{% endfor %}
</div>
I would like this to render like below
<div>
<h4>specs</h4>
<svg class='spec-icon'><use xlink:href="#icons_tee"/></svg>
<svg class='spec-icon'><use xlink:href="#icons_mobile"/></svg>
</div>
for every neseted name:vale pair under spec:, I would like there to be a unique svg element created with that nested value included in the #id
???
Try this:
---
layout: post
title: title of this post
spec: [tee, mobile]
---
Then:
<div>
<h4>specs</h4>
{% for item in page.spec %}
<svg class='spec-icon'><use xlink:href="#icons_{{ item }}"/</svg>
{% endfor %}
</div>
Hope to have helped! Let me know if this works, yeah?
I have a problem, I only want to access a specific location of array,
Lets say I have this code
{% set total = val.listCompanies|length%}
{% if total > 1 %}
<td>
<button id="viewcompany"
type="button"
class="pop btn btn-info"
data-toggle="popover"
title="User Company List"
data-content='
{% for key1, val1 in val.listCompanies %}
{{ val1.CompanyName }}<br>
{% endfor %}'
data-placement="right"
data-html = "true">
see company
</button>
</td>
{% endif %}
{% if total < 2 %}
<td>
{% for key1, val1 in val.listCompanies %}
<center>
{{ val1.CompanyName }}<br>
</center>
{% endfor %}
</td>
{% endif %}
I want to make a button, that if it contain only one array inside it, I dont have to use the popover button, but if it has more than 1 array inside of its, then I have to show it inside of the popover button.
The thing is I cant access the specific array, to add more logic..
If your val.listCompanies contains numeric keys, you can access the first one by using:
val.listCompanies[0]
If your val.listCompanies has generated keys and you want to access the first one, you can use:
val.listCompanies|first
If your val.listCompanies has generated keys and you want to access the Nth one, you can use:
val.listCompanies|slice(n, 1)|first
Working demo
Ok I have a base.html and I try to use that for my header menu and footer. In my other template I loop over items and display them on the page. My problem is the the other template is repeating my base.html like it's in the loop. I hope someone can show me the error in My ways.
Here is my base.html code:
<div class="menu">
<ul class="nav">
<li>Home</li>
<li>New Entry</li>
<li>Sign-up</li>
{% if user %}
<li>{{user.name}}</li>
<li>Log-Out</li>
{% else %}
<li>Log-In</li>
{% endif %}
</ul>
This is in the base.html also but didn't paste correctly.
<div id="content">
{% block content %}
{% endblock %}
</div>
And here is the sub template code:
{% extends "base.html" %}
{% block content %}
{% for p in posts %}
{{ p.render() | safe }}
<br><br>
{% endfor %}
<div>
{{text}}
</div>
{% endblock %}
Please help
Edit:
edit2: removed link and found my problem I was calling the wrong html file in render()
Be kind Newbie here
Looks ok. Are you sure you don't have a loop in the python code that renders the template?
How to use this solution https://stackoverflow.com/a/10067749/604240 in jinja 2 template?
I agree my question was due to lack of knowledge than problem. Eventually I figured it out how to achieve it. Basically I didn't know how to link loop from python code to query so it's available to Jinja2 template.
Although correct solution might be to use map() with callback function https://developers.google.com/appengine/docs/python/ndb/queryclass#Query_map but I am using temporary solution which is working for me for now.
query = Image.query()
query2 = query.filter(Image.is_slider == 'yes')
for item in query2:
item.parent = item.key.parent().get()
and in template
{% for item in query2 %}
<img src="{{ item.url }}=s1000" alt="{{ item.title }}" title="{{ item.title }}" />
<h2>{{ item.title }}</h2>
<h3>{{ item.gallery }}</h3>
Go to gallery
{% endfor %}
Why don't you just try {{ item.key.parent().get().slug }} on your jinja2 template (assuming that slug is a property of your Gallery entity).