Jinja2 template evaluate variable as attribute - python-3.x

I have a Jinja2 Template I'm working on for a database editing app, and I'm trying to make it 'extendible' - rather than hard-coding the editing page, I'm passing a list of attributes that I want in the table, and using a for loop to iterate over them. It works aside from one thing - in the hardcoded version, I use an attribute of an object that's being passed to see if that value has been set (they are all boolean), but I can't see how to get jinja2 to take the 'capability' and use that as an attribute of the 'pupil' object; i would have used 'eval' in Python, but can't see how to get this to work. Here's an idea of the code:
{% for capability in capability_list %}
<tr>
<td>{{ capability }}</td>
<td>
{% if pupil.capability %}
<img src="{{request.static_url('gdpr_permissions:static/tick.png')}}" width="25">
{% else %}
<img src="{{request.static_url('gdpr_permissions:static/cross.png')}}" width="25">
{% endif %}
</td>
<td>
<div class="onoffswitch">
<input type="checkbox" name="{{ capability }}" class="onoffswitch-checkbox" value ='No' id="{{ capability }}" checked>
<label class="onoffswitch-label" for="{{ capability }}">
<span class="onoffswitch-inner"></span>
<span class="onoffswitch-switch"></span>
</label>
</div>
</td>
</tr>
{% endfor %}
It's the {% if pupil.capability %} part that doesn't work - I want this to become (say) pupil.web_access and pupil.database_access etc., following the capability list which is being iterated over.
Any ideas on how to get this working with jinja2, or how else it can be approached? The other idea I had was to iterate over the current settings in the python backend and then pass a list of booleans separately, but this seems to be adding an extra level of complexity.

This is because you are passing in a string instead of an attribute. Use getattr() instead. Do something like getattr(pupil, capability)

Related

Is there any way to iterate over list inside list in django template?

I have a list a = [[1000,3000], [4000-5000]], i would like to show it has
1000-3000
4000-5000 in template. But i'm getting only the first object.
What i tried is,
products.html
{% for i in price_group %}
<label>
<input class="uk-radio" type="radio" onchange="$('#form').submit();" name="price" value="{{ i.0.0 }};{{ i.0.1 }};price;first" checked>
{{ i.0.0 }} - {{ i.0.1 }}
</label>
{{ price_group.pop.i }}
{% endfor %}
I used pop functionality to remove current from the list and take the next one, but it's not working as expected.
it is showing only the first element in the list. Please correct me if I am wrong. What I want is it has a price range like.
1000-3000
4000-5000..like wise. Please help me.
You are accessing only first element of the list, you need to update your code to access all the elements like this:
{% for i,j in price_group %}
<label> <input class="uk-radio" type="radio" onchange="$('#form').submit();" name="price" value="{{ i }};{{ j }};price;first" checked>
{{ i }} - {{ j }}
</label>
{% endfor %}

Just a regular block reuse with Twig - how to?

Imagine we have a block template which we want to use many times on a page. And every time we need to do three things:
set a class on the top level
set a title
add some content
How to achieve this on Twig?
I know about macro, but it doesn't take content.
I know about block, but it doesn't take parameters.
So... how to do this in a normal way?
Since I don't know how, I'll use an imaginary constructs 'blockdef' and 'blockuse' later on to demonstrate the task (which is absolutely ordinary).
So let's say we have this cute Twig block template:
blocks.twig:
{% blockdef myblock(class, title) %}
<div class="block {{class}}">
<div class="inner">
<div class="title">{{title}}</div>
<div class="content">{{content}}</div>
</div>
</div>
{% endgoodblock %}
And want to use it like this:
main.twig:
{% blockuse myblock('c1', 'Title1' %}
<p>Block 1 content</p>
{% endblockuse %}
{% blockuse myblock('c2', 'Title2' %}
<p>Block 2 content</p>
{% endblockuse %}
{% blockuse myblock('c3', 'Title3' %}
<p>Block 3 content</p>
{% endblockuse %}
Is there anything like this?
UPDATE. For example, this is how it's solved on Jade:
mixin myblock(cls, title)
.block(class=cls)
.inner
.title= title
.content
block
+myblock('c1', 'Title1')
p Block 1 content
+myblock('c2', 'Title2')
p Block 2 content
+myblock('c3', 'Title3')
p Block 3 content
You could use include with:
{% include 'template.html' with {'class': 'class', 'title': 'title', 'content: 'content'} %}

Twig loop.first not working

I have the following :
{% for field in fields -%}
<div class="item{% if loop.first %} active{% endif %}">
{{ field.content }}
</div>
{%- endfor %}
but it's adding the active class to every field wrapper, rather than just the first which is my intention.
Thanks Darkbee. User malfunction here. The code was in a nested template file ( Drupal ) and the loop I thought I was iterating through was actually in a higher level template file.

If statement in Twig (for Particle in Joomla)

Trying to edit a particle in Joomla -- I'm fairly new to twig and I'm trying to list information based on a selection in vertical tabs. I have an on-click refresh for my li edit that makes a tab "selected" and creates my internal url:
{% for item in particle.items %}
<li>
<a href="/Joomla/about-the-library/locations#{{ loop.index }}">{{ item.title|e }}
<img src="{{ url(item.image)|e }}" alt="{{ item.title|e }}">
<div class="g-flexslider-carousel-item-image-preview-icon"></div>
</a>
</li>
{% endfor %}
This is all well and good, but I ran into an issue when trying to display the data associated with the selected item. I tried to create a variable to check my items against, but the variable doesn't seem to be coming back as an integer, and I've tried a few things:
{% set branch = app.request.pathinfo|trim('/Joomla/about-the-library/locations#') %}
{% if loop.index == branch %}
<div class="g-flexslider-showcase-item-content-container">
<div class="g-flexslider-showcase-item-image">
<img src="{{ url(item.image)|e }}" alt="{{ item.title|e }}">
</div>
Can anyone tell me what I'm doing incorrectly?
(I found that get current url in twig template? helped, but I'm not sure I'm using the answers provided correctly. I've also sifted through the Twig Documentation for a couple hours to no avail.)
[Nov 2016] - This is still what "my" code looks like for this section. It seems to just be a problem with this if statement, as the "else" statement (which I'm using for debugging purposes) keeps coming through.
{% for item in particle.items %}
{% if app.request.get('name') == item.URLname|e %}
<p>You have branched {{ item.title|e }} correctly. </p>

In a nested for-loop, how can I access the outer loop index in a jinja template?

{{loop.index}} correctly dereferences the innermost loop. I'm not seeing a way to identify which loop index I'd like, however, if I have more than one loop nested.
http://jinja.pocoo.org/docs/dev/templates/
YES. This part of the documentation exactly answers my question!
The special loop variable always points to the innermost loop. If it’s
desired to have access to an outer loop it’s possible to alias it:
<table>
{% for row in table %}
<tr>
{% set rowloop = loop %}
{% for cell in row %}
<td id="cell-{{ rowloop.index }}-{{ loop.index }}">{{ cell }}</td>
{% endfor %}
</tr>
{% endfor %}
</table>
http://jinja.pocoo.org/docs/dev/tricks/#accessing-the-parent-loop

Resources