generate unique id in each loop of for loop django template - html

I need to generate unique id in each loop instead of ````city-selected```
{% for form in formset.forms %}
<tr>
{% for field in form %}
<td class="input_td{% if field.errors %} error_td{% endif %}">
<select name="city-select" id="city-select"></select>
</td>
{% endfor %}
<td class="delete_formset_td"></td>
</tr>
{% endfor %}
How can I generate it here?
I need some thing like this for ids:
output:
city-1
city-2
city-3
...

You can use {{ forloop.counter }}. It gives you the loop iteration as a number.
See here.
{% for field in form %}
<!-- your html -->
city-{{ forloop.counter }}
{% endfor %}

Related

Why do I not get labels rendered from CharField when using DJANGO formset

I have a form with 2 CharFields. Both have label="xyz".
If I use this form in a formset, the lables are not shown in the HTML
I have tried looking at the rendered HTML and the label is missing. I have tried just a form and that works.
Forms:
class WindingVoltsSpecifier(forms.Form):
winding_name = forms.CharField(max_length=20, label="Winding name")
voltages = forms.CharField(max_length=20, label="Voltages")
View:
def add_mains_transformer_primary_configs(request):
# Add a new config
# Create the formset, specifying the form and formset we want to use.
# From https://whoisnicoleharris.com/2015/01/06/implementing-django-formsets.html
VoltsSpecifierFormSet = formset_factory(WindingVoltsSpecifier)
if request.method == 'POST':
pass
else:
mt_config_form = MainsTransformerConfiguration()
volts_formset = VoltsSpecifierFormSet()
context = {
'mt_config_form' : mt_config_form,
'volts_formset' : volts_formset,
}
return render(request, 'designer/mains_configs.html', context)
Template:
{% extends 'designer/base.html' %}
{% load crispy_forms_tags %}
{% block title %}configuration{% endblock %}
{% block content %}
{% load static %}
<h1>Configuration</h1>
<form method="post">
{% csrf_token %}
{{ mt_config_form|crispy }}
{{ volts_formset.management_form|crispy }}
{% for volts_form in volts_formset %}
<table>
{% for form in volts_form %}
{{ form }}
{% endfor %}
<table>
<!--<div class="volts-formset">
{{ volts_form.winding_name }}
{{ volts_form.voltages }}
</div>
-->
{% endfor %}
{% if volts_formset.non_form_errors %}
{% for error in volts_formset.non_form_errors %}
{{ error|escape }}
{% endfor %}
{% endif %}
<input type="submit" value="Update Profile" class="button" />
</form>
<script>
$('.volts-formset').formset({
addText: 'add winding',
deleteText: 'remove'
});
</script>
{% endblock %}
I would expect the label to be beside the field.
Labels are not rendered with fields, you will have to do a {{ FIELD.label_tag }}.
It will be something like this:
<table>
{% for field in volts_form %}
{{ field.label_tag }}
{{ field }}
{% endfor %}
<table>
More info: Looping over the forms fields - Django documentation
Hope this solution to works!
{% for field in volts_forms %}
{{ field.name}} <!-- label name -->
{{ field }}<!-- ex. input -->
{% endfor %}

Jekyll nested include with for loop

I'd like to use a {% for %} loop in an included file, to avoid repeating logic to create the loop array (it's an assign with multiple where_exps).
But I'd like to use different content depending on where I include the loop, so sometimes I will do this:
{% for i in a %}
<li>{{ i.name }}</li>
{% endfor %}
and sometimes:
{% for i in a %}
<loc>{{ i.url }}</loc>
{% endfor %}
How can I achieve this? So far I have to put each of the inner contents in their own template, so I would have files like below, but I'd like to avoid the extra template files, and just keep that content in the appropriate main file:
html_template.html:
<li>{{ i.name }}</li>
xml_template.xml:
<loc>{{ i.url }}</loc>
page_loop.html:
{% assign a = "logic I don't want to repeat" %}
{% for i in a %}
{% include {{ include.inner_template }} %}
{% endfor %}
html_main.html:
{% include page_loop.html inner_template="html_template.html" %}
xml_main.xml:
{% include page_loop.html inner_template="xml_template.xml" %}
It would probably be another more elegant (?) solution developing a plugin, but quickly modifying your code, in _includes/page_loop.html:
{% assign a = "something" %}
{% for i in a %}
{%if include.type == "name"%}
<li>{{ i.name }}</li>
{%else if include.type == "url"%}
<loc>{{ i.url }}</loc>
{%endif %}
{% endfor %}
Then each time you include page_loop.html pass an additional parameter specifying which type of output you want:
{% include page_loop.html type="name" %}
or
{% include page_loop.html type="url" %}

Liquid markup sorting the output

I am trying to display a list of all articles using liquid markup. I've got this code which displays them properly, however I want to be able to sort by the modified date descending (most recent article on top). How can this be accomplished?
I was thinking that perhaps I need to create a new array with all articles in it and then sort that, but I am not sure how to do that. Also note that I want to sort ALL of my articles by date, not just within each folder.
{% for category in portal.solution_categories %}
{% if category.folders_count > 0 %}
{% for folder in category.folders %}
{% for article in folder.articles %}
{{ article.title }} - {{ article.modified_on | short_day_with_time }} <br>
{% endfor %}
{% endfor %}
{% endif %}
{% endfor %}
Thanks!
You can use a variable to sort the list of articles and then iterate that variable.
{% for category in portal.solution_categories %}
{% if category.folders_count > 0 %}
{% for folder in category.folders %}
{% assign sorted = (folder.articles | sort:date) %}
{% for article in sorted %}
{{ article.title }} - {{ article.modified_on | short_day_with_time }} <br>
{% endfor %}
{% endfor %}
{% endif %}
{% endfor %}

How to loop through categories in a Jekyll collection

I'm trying to loop through categories that have been added to collection posts. For the default 'posts' section it's as easy as:
{% for category in site.categories %}
{{ category }}
{% endfor %}
But I can't seem to get this working for my collection. I thought it would be something along the lines of:
{% for category in my_collection.categories %}
{{ category }}
{% endfor %}
But that doesn't seem to work. Any help would be appreciated.
for anyone needing the answer to this...I've managed to solve this by adding all unique 'my_collection' categories to an array then looping through that. Here's the code:
<!-- create categories array-->
{% assign categories_array = "" | split:"|" %}
<!--Add each unique 'my_collection' category to the array-->
{% for post in site.my_collection %}
{% for category in post.categories %}
{% assign categories_array = categories_array | push: category | uniq %}
{% endfor %}
{% endfor %}
<!--Output the categories-->
{% for category in categories_array %}
{{ category }}
{% endfor %}
you can grab the name of each category like so:
{% for category in site.categories %}
{{ category | first | strip_html }}
{% endfor %}
You first have to declare the collection
{%a assign col = site.COLLECTIONNAME %}
Then you can loop inside the collection
{% for cat in col %}
{{ col.name }}
{% endfor %}

Twig Set array value based on key

i found around here a similar question like this one but the answers from there didn't help me.
<table>
<tr>
<th>Permission</th>
{% for role in roles %}
<th>{{role}}</th>
{% endfor %}
</tr>
{% for permission in permissions %}
{% if permission.PermissionName != currPerm %}
{% if currPerm != '' %}
<tr>
<td class="current-permission">{{currPerm}}</td>
{% for perm in permArray %}
<td>{{perm}}</td>
{% endfor %}
</tr>
{% endif %}
{% set currPerm = permission.PermissionName %}
{% set permArray = default %}
{% endif %}
{% set permArray[permission.RoleId] = '&check;' %}
{% endfor %}
<tr>
<td>{{currPerm}}</td>
{% for perm in permArray %}
<td>{{perm}}</td>
{% endfor %}
</tr>
</table>
The code above contains this line
{% set permArray[permission.RoleId] = '&check;' %}
Where i have problems setting the value for each key that it contains i tried with merge but with any luck it only adds a new key to the array and that's all.
If you have any other advices for this code i'm all ears.
With Twig you are not allowed to assign a value to an array key like this.
You must use the merge filter to do something like :
{% set permArray[permission.RoleId] = permArray|merge({permission.RoleId:'&check;'}) %}