Unable to correctly parse URLs using Django template language - django

I currently am trying to link a researcher's name if they provided a link, otherwise if they provide a blank input or N/A, then I choose not to link their name. I use the information from the researcher object using Django's template language, but when I check the result it ends up linking all of them, and those without input just have href = "" which links back to the homepage.
I've tried using {{r.website_link|length}} instead, but that just creates errors and the page won't load. I'm a newbie to frontend so I'm not sure if my "if" statement is incorrect or if my HTML logic is incorrect.
<div>
{% for r in researcher %}
<div class="researcher">
{% if "{{r.website_link}}" != "N/A" and "{{r.website_link}}" != "" %}
<p><a class="researcherwebname" href="{{ r.website_link }}">{{ r.fullname|title}}</a> | {{ r.institution }} | {{r.position}} | <i>{{ r.des|capfirst }}</i></p>
{% else %}
<p> {{ r.fullname|title}} | {{ r.institution }} | {{r.position}} | <i>{{ r.des|capfirst }}</i></p>
{% endif %}
</div>
{% endfor %}
</div>
I expect it to link researchers with an actual r.website_link input, otherwise the name should be unlinked.

please try
{% if r.website_link %}
{% if r.website_link != "N/A" %}
{# display researcher #}
{% endif %}
{% endif %}

Related

Heading from product filter

I'm using the Foundry theme and on the /products page. I have links to the different categories of products. These take you to /category/______. There is a <h1> heading, which has a default of value Shop. I want the value to represent the current category. I tried the following code, but the heading was just blank.
<h1>
...
{% elsif page.full_url contains "category/" %}
{% for category in categories.all %}
{% if page.full_url contains {{ category.permalink }} %}{{ category.name }}{% endif %}
{% endfor %}
...
</h1>
Examples:
page.full_url returns https://website/category/wall-hangings
category.permalink returns wall-hangings
I also tried a method using:
{{ page.full_url | remove: "https://website/category" | replace: "-" " " | capitalize }}
However, the replace method doesn't insert spaces.
I overcomplicated my original approach. Using {{ page.name }} returns the category name, so using this in the heading tag worked.

How to show the first true element after if condition in for loop in django template?

I have a for loop in Django template. After that, I check for coincidences. But in some cases, there are might be 3 coincidences. I need to show only the first coincidence. Now, my code returns the name for 3 times, because, there are 3 coincidences
{% for ip in ips %}
{% if d.name == ip.name %}
<strong>{{ d.name}} </strong>
{% endif %}
{% endfor %}
SOLUTION
It is impossible to break forloop in django template, so I decided to change in views.py through queryset distinction of similar names
ips = Point.objects.defer('point').order_by('name').distinct('name')
I don't recommend doing this in Django Template , but in views itself. But if you can't then you can use {{ forloop|break }}.
Something like this :
{% for ip in ips %}
{% if d.name == ip.name %}
{{ forloop|break }}
<strong>{{ d.name}} </strong>
{% endif %}
{% endfor %}
Check the small snippet example here...

Simple liquid markup for Shopify not working ...?

I made this simple markup on a Shopify product-template.liquid section. It's not returning the second image though on different products outside of the ones specified.
{% if product.handle == "e" or "f" %}
{{ '3.png' | asset_url | img_tag }}
{% else %}
{{ '4.png' | asset_url | img_tag }}
{% endif %}
This seems pretty straight forward according to Shopify's documentation. However I can't get 4.png to come up on the other products in the store.
This seems like a really basic problem, but it's doing me in! What am I missing?
You can't chain conditional statements in liquid you need to redefine the comparison.
{% if product.handle == "e" or product.handle == "f" %}
{{ '3.png' | asset_url | img_tag }}
{% else %}
{{ '4.png' | asset_url | img_tag }}
{% endif %}

NoReverseMatch when rendering page

I seem to know where the issue is located since I can get around it, but for getting around it I have to sacrifice a function I really want to keep.
Here is the relevant code in the non-working state:
{% if sections %}
{% for item in sections %}
<a class="sections" href="{% url 'sections:generate' item.section.slug %}">{{ item.section.title }}</a>
{% for subsection in item.subsections %}
<p>{{ subsection.title }}</p>
{% endfor %}
{% endfor %}
{% else %}
<p>Error retrieving sections or no sections found</p>
{% endif %}
The problem part above is in the link tag. Let me explain by showing the related view.py:
def index(request):
sections = Section.objects.all()
context = {
'sections': [],
}
for section in sections:
context.get("sections").append(
{
'section': section,
'subsections': get_subsections(section),
}
)
return render(request=request, template_name='index.html', context=context)
So, 'sections' is an iterable list of items, containing for every items a dictionary with two entries. One, 'section' and one 'subsection'. There are multiple subsections for every section, this is what I really want to accomplish.
Ordinarily, when not bothering with subsections and simply iterating over a list of sections works fine. The template code for that would look something like:
{% for section in sections %}
{{ section.title }}
{% endfor %}
NOTE! The code above works just fine! But as soon as I add 'sections' as a list of dictionaries and have to reference the slug by item.section.slug the pages stop rendering.
Please advise.
Try using tuples:
View:
context['sections'] = [(section, tuple(get_subsections(section))) for section in sections]
Template:
{% for section, subsections in sections %}
<a class="sections" href="{% url 'sections:generate' section.slug %}">{{ section.title }}</a>
{% for subsection in subsections %}
<p>{{ subsection.title }}</p>
{% endfor %}
{% endfor %}

Variable subtraction in django templates

It is able to write {{ myval.add:5 }}, {{ myval|add:value }} and even {{ myval|add:-5 }}.
However, I can't find out what I should type to add value * -1 like {{ myval|add:-value }}. This doesn't work, sadly.
You need to use double quotes:
{{ myval|add:"-5" }}
This subtracts five from myval.
The built-in Django template tags/filters aren't all-encompassing, but it's super easy to write your own custom template tags: https://docs.djangoproject.com/en/dev/howto/custom-template-tags/
You could make your own subtract template tag pretty easily:
#register.filter
def subtract(value, arg):
return value - arg
Use django-mathfilters from PyPI: https://pypi.python.org/pypi/django-mathfilters
To install :
$ pip install django-mathfilters
Then add mathfilters in your INSTALLED_APPS.
In template:
{% load mathfilters %}
<ul>
<li>8 + 3 = {{ 8|add:3 }}</li>
<li>13 - 17 = {{ 13|sub:17 }}</li>
{% with answer=42 %}
<li>42 * 0.5 = {{ answer|mul:0.5 }}</li>
{% endwith %}
{% with numerator=12 denominator=3 %}
<li>12 / 3 = {{ numerator|div:denominator }}</li>
{% endwith %}
<li>|-13| = {{ -13|abs }}</li>
</ul>
I recently started working with Django and stumbled upon this one as well: I needed a very simple template loop that stops printing after n times and shows a "more" link to toggle the rest of the items.
With great interest I read the struggle of people trying to understand why this is not being added to the Django default filters (since before 2013). I didn't feel like creating a custom template tag and I kind of found a way to subtract 2 variables using strings and add in combination with with and stringformat
Let's say I have a list of items where I want to print the first 2 and hide the rest, showing how many hidden items are there, eg.
John, Anna and 5 others like this (when given a list of 7 items)
As long as the number of visible items is harcoded in the template (eg. 2), it's possible to add the negative 2 |add:"-2", but I wanted the number of visible items to be a variable as well. The Math-filter library as suggested above doesn't seem up to date (I haven't tested it with Django 2.x).
The trick seems to be to use the add helper to concat the strings "-" with the integer as string, so it can be coerced back to a negative integer in a any consecutive calls to the add helper. This doesn't work however if the value is not a string, so that's where the stringformat helper comes in.
With string value
template posts.html (note how visible is explicitely passed as string - alternative below)
{% for post in posts %}
<h4>{{ post.title }}</h4>
...
{% include 'show_likes.html' with likes=post.likes visible="3" %}
{% endfor %}
template show_likes.html (note the add:0 to make the boolean operator work)
{% with show=visible|default:"2" %}
{% for like in likes %}
{% if forloop.counter <= show|add:0 %}
{% if not forloop.first %},{% endif %}
{{ like.username }}
{% endif %}
{% endfor %}
{% if likes|length > show|add:0 %}
{% with rest="-"|add:show %}
and {{ likes|length|add:rest }} more
{% endwith %}
{% endif %}
like this
{% endwith %}
Alternative with integer
You could just convert your integer to a string in the calling template using |stringformat:"d"
If however the number of visible items you want to show is an integer, you'll have to add a call to stringformat:"d" to have it converted to string
template posts.html
{% for post in posts %}
<h4>{{ post.title }}</h4>
...
{% include 'show_likes.html' with likes=post.likes visible=3 %}
{% endfor %}
template show_likes.html
{% with show=visible|default:2 %}
{% with show_str=show|stringformat:"d" %}
{% for like in likes %}
{% if forloop.counter <= show %}
{% if not forloop.first %},{% endif %}
{{ like.username }}
{% endif %}
{% endfor %}
{% if likes|length > show|add:0 %}
{% with rest="-"|add:show_str %}
and {{ likes|length|add:rest }} more
{% endwith %}
{% endif %}
{% endwith %}
{% endwith %}
Since I'm a very beginner with Django and Python, I'm pretty sure this approach is far worse than actually creating a custom helper! So I'm not suggesting anyone should be using this. This was just my attempt on trying to solve this with the available template helpers and without any custom stuff.
Hope this helps
Lo primero es multiplicar por -1 para convertirlo en una valor negativo y guardarlo en una variable y posterior a usar la suma
The first thing is to multiply by -1 to turn it into a negative value
and save it in a variable and then use the add
{% widthratio val2 1 -1 as result %}
{{result|add:val1}}
After search I found that I can make {% with var=value %} with filters to make the arithmetic operations "with other variables or not"
For example: I have x = 5 and y = 3 and need to add the y's value to x value, all what I need is these steps:
1- Create variable x : {% with x=5 %}
2- Create variable y : {% with y=3 %}
3- In my HTML tags, say <h1>, write that : <h1>{{ x|add:y }}</h1>
4- Close the y's with : {% endwith %}
5- Close the x's with : {% endwith %}
Hope it works with you, it worked with me.
{% with i=3 %}
{% with x=1 %}
<h1>{{i|add:x}}</h1> <!-- result is 4 -->
{% endwith %}
{% endwith %}