I have an car object in django view as follows:
'damages': [
{
"location": "Voorbumper",
"type": "Kras(10 cm, leger)",
"severity": "Light damage",
'comment': "This is some comment.",
"images": [
'http://pathtophoto.jpg',
'http://pathtophoto.jpg'
]
},
{
"location": "Vleugel rechts voor",
"type": "Deuk (Licht)",
"severity": "",
'comment': "",
"images": [
'http://pathtophoto.jpg',
'http://pathtophoto.jpg',
'http://pathtophoto.jpg'
]
},
{
"location": "Deur links voor",
"type": "Kras (5 cm, leger)",
"severity": "",
'comment': "",
"images": [
'http://pathtophoto.jpg'
]
},
{
"location": "Waterlijst",
"type": "Beschadigd",
"severity": "",
'comment': "",
"images": []
},
{
"location": "Antenne",
"type": "Ontbreekt",
"severity": "",
'comment': "",
"images": [
'http://pathtophoto.jpg'
]
},
{
"location": "Antenne",
"type": "Ontbreekt",
"severity": "",
'comment': "",
"images": []
}
]
I want to loop through that object and show the images of the damages. But I want first to show the damages with images, and the the damages without images with appropriate title.
In a django template I try to d it as follows:
{% for damage in car.damages %}
{% if damage.images|length > 0 %}
<div class="width-100 pad text-left primary-bg">{% trans "Shades met foto's" %}</div>
<div class="width-100 mar-top clear-float">
<div class="width-30 bord-my-way pad-half damage-info">
<div class="mar-btm-half"><b>{{ damage.location }}</b></div>
<div class="mar-btm-half">{{ damage.type }}</div>
<div class="mar-btm-half">{{ damage.severity }}</div>
<div class="mar-btm-half">{{ damage.comment }}</div>
</div>
<div class="width-70 pad-lft damage-photos">
{% for image in damage.images|slice:"3" %}
<div class="width-33 pad-rgh">
<img src="{{ image }}" class="width-100"/>
</div>
{% endfor %}
</div>
<div class="clear-float"></div>
{% if forloop.counter == 7 or forloop.counter == 14 or forloop.counter == 21 %}
<p style="page-break-before: always"></p> {% endif %}
</div>
{% endif %}
{% endfor %}
{% for damage in car.damages %}
{% if damage.images|length == 0 %}
<div class="width-100 pad text-left primary-bg mar-top">{% trans "Shades zonder foto's" %}</div>
<div class="green-bg">{{ damage.location }}</div>
{% endif %}
{% endfor %}
Thus, I first loop through damages where damage.images|length > 0 and then in the second for I check if there is no images with damage.images|length == 0. But the title is shown for every for loopiteration.
I could place the title's for the for loop. Something like:
<div> Damages with photos </div>
{% for damage in car.damages %}
{% if damage.images|length > 0 %}
// Show it
{% endif %}
{% endfor %
And
<div> Damages without photos </div>
{% for damage in car.damages %}
{% if damage.images|length == 0 %}
// Show it
{% endif %}
{% endfor %
But sometimes I have only damages with images or only damages without images and then I see the title although I do not have any damages to show.
Is there any way to do something only once inside the if statement, something like:
{% for damage in car.damages %}
{% if damage.images|length > 0 %}
<div>Damages with the photos</div> // Show it only once when it comes here
// Show the damages with photos
{% endif %}
{% endfor %}
{% for damage in car.damages %}
{% if damage.images|length == 0 %}
<div>Damages without the photos</div> // Show it only once when it comes here
// Show the damages without photos
{% endif %}
{% endfor %}
Any idea how to solve it?
I'm not overly familiar with Django and Python anymore, but I guess you could do a preliminary check to see if there are damages with or without images in there.
damages_with_images = [d for d in damages if d.images.length > 0]
damages_without_images = [d for d in damages if d.images.length == 0]
And then just loop over these two separate arrays, and only print the heading if they are not empty...
{% if damages_with_images|length > 0 %}
put heading1
{% endif %}
# ... loop ...
{% if damages_without_images|length > 0 %}
put heading2
{% endif %}
# ... loop ...
Of course this has worse performance because of multiple loops.
What I would do in your position is
Either pass two separate QuerySets in the template, the first would include damages with images and the other damages without images.
Leave the QuerySet as is and create two custom template filters that would do the same job as the step #1 above.
Case 1:
# views.py
def my_view(request):
damages_w_img = Damage.objects.filter(images__isnull=False)
damages_wo_img = Damage.objects.filter(images__isnull=True)
return render(request, 'template.html', locals())
<!-- template.html -->
{% if damages_w_img.exists %}
<h1>This list of damages contains images</h1>
{% for damage in damages_w_img %}
do stuff here, each damage has an image
{% endfor %}
{% endif %}
{% if damages_wo_img.exists %}
<h1>This list of damages does not contain images</h1>
{% for damage in damages_wo_img %}
do stuff here, each damage does not has an image
{% endfor %}
{% endif %}
Case 2:
# custom_template_filter.py
from django import template
register = template.Library()
#register.filter
def with_images(damages):
return damages.objects.filter(images__isnull=False)
#register.filter
def without_images(damages):
return damages.objects.filter(images__isnull=True)
<!-- template.html -->
{% with damage_w_img=car.damages|with_images damage_wo_img=car.damages|without_images %}
{% if damages_w_img.exists %}
<h1>This list of damages contains images</h1>
{% for damage in damages_w_img %}
do stuff here, each damage has an image
{% endfor %}
{% endif %}
{% if damages_wo_img.exists %}
<h1>This list of damages does not contain images</h1>
{% for damage in damages_wo_img %}
do stuff here, each damage does not has an image
{% endfor %}
{% endif %}
{% endwith %}
Related
When I save my django-html file the following changes occur in auto formatting.
{% extends 'base.html' %} {% block content %} {% if dice %} {% for die in dice
%}
<img src="{{die.image.url}}" alt="{{die.name}}" />
{% endfor %} {% endif %} {% endblock %}
I want to have something like the following instead...
{% extends 'base.html' %}
{% block content %}
{% if dice %}
{% for die in dice %}
<img src="{{die.image.url}}" alt="{{die.name}}" />
{% endfor %}
{% endif %}
{% endblock %}
I have Beautify installed and my settings are as follows...
"emmet.includeLanguages": {
"javascript": "javascriptreact",
"django-html": "html"
},
"files.associations": {
"**/*.html": "html",
"**/templates/*/*.html": "django-html",
"**/templates/*": "django-txt",
"**/requirements{/**,*}.{txt,in}": "pip-requirements"
},
"beautify.language": {
"html": ["htm", "html", "django-html"]
},
I have several blog posts that fall under one umbrella blog post. For example, I have several posts about SQL Zoo tutorials, but I want to be able to link them all up to one "umbrella" post so that I only have one SQL Zoo post on the index page of my blog. I got this idea from: https://codeasashu.github.io/implement-series-post-jekyll-part-2/ and tried to follow the instructions, but now my series post does not show up on my index page. I have the following code in a file called post-series.html located in my _includes folder:
{% assign seriesarray = '|' | split : '|' %}
{% assign seriestitle = '' %}
{% assign serieslabel = '' %}
{% assign sortedposts = (site.posts | sort: 'date') %}
{% for post in sortedposts %}
{% if post.series and page.series_slug != nil and post.series == page.series_slug %}
{% capture postitem %} <li> {{ post.title }} </li> {% endcapture %}
{% assign seriesarray = seriesarray | push: postitem %}
{% assign seriestitle = 'Posts in this series' %}
{% assign serieslabel = 'Series Post' %}
{% elsif post.series != nil and page.series != nil and page.series == post.series %}
{% assign pageurl = page.url | split:'/' | last %}
{% assign posturl = post.url | split:'/' | last %}
{% if pageurl != posturl %}
{% capture postitem %} <li> {{ post.title }} </li> {% endcapture %}
{% else %}
{% capture postitem %} <li> {{ post.title }} </li> {% endcapture %}
{% endif %}
{% assign seriesarray = seriesarray | push: postitem %}
{% endif %}
{% if post.series_slug != nil and page.series != nil and page.series == post.series_slug %}
{% capture series_title %} {{ post.title }} {% endcapture %}
{% assign seriestitle = 'This posts is part of series - ' | append: series_title %}
{% assign serieslabel = 'This posts is part of series - ' | append: series_title %}
{% endif %}
{% endfor %}
{% capture serieslayout %}
{% if seriesarray.size > 0 %}
<hr />
<div class="panel">
<div class="panel-body">
<h4> {{ seriestitle }} </h4>
<ul id="post-series-list">
{% endif %}
{% for post in seriesarray %} {{ post }} {% endfor %}
{% if seriesarray.size > 0 %} </ul> </div> </div> {% endif %}
{% endcapture %}
and the following code from my index.html file in the root of my directory:
---
layout: index
---
<div id="home">
<h1>{{ site.title }}</h1>
<hr />
<ol class="posts">
{% for post in paginator.posts %}
{% assign seriesPost = nil %}
{% if post.series == nil %}
{% if post.series_slug != nil %} {% assign seriesPost = '(Series)' %} {% endif %}
<li class="post-listing">
<img class="post__image" src="/static/img/{{ post.cover_image}}" alt="{{ post.cover_alt }}" />
<div class="post__text">
<a class="post__title" href="{{ post.url }}">{{ post.title }}</a><br>
<span>
{{ post.date | date_to_string }} •
{% assign words = post.content | number_of_words %}
{% if words < 360 %}
1 min read
{% else %}
{{ words | divided_by:180 }} min read
{% endif %}
</span>
{{ post.excerpt }}
</div>
</li>
{% endif %}
{% endfor %}
</ol>
<!-- <div class="sidebar-right sidebar"></div> -->
<!-- <ul>
{% for post in paginator.posts %}
<li>
{{ post.title }}
{{ post.excerpt }}
</li>
{% endfor %}
</ul> -->
<!-- Pagination links -->
{% if paginator.total_pages > 1 %}
<ul class="pagination pagination-sm">
{% if paginator.previous_page %}
<li>«</li>
{% else %}
<li class="disabled"><span aria-hidden="true">«</span></li>
{% endif %}
<li>First</li>
{% for page in (1..paginator.total_pages) %}
{% if page == paginator.page %}
<li class="active"><a>{{ page }}<span class="sr-only">(current)</span></a></li>
{% elsif page == 1 %}
<li>{{ page }}</li>
{% else %}
<li>{{ page }}</li>
{% endif %}
{% endfor %}
<li>Last</li>
{% if paginator.next_page %}
<li>»</li>
{% else %}
<li class="disabled"><span>»</span></li>
{% endif %}
</ul>
{% endif %}
</div><!-- end #home -->
My full repo can be found here: https://github.com/thedatasleuth/thedatasleuth.github.io
In your index.html, {% if post.series == nil %} simply bares posts containing a series: someserie front matter variable to be printed.
For the second problem (note that on SO, you are supposed to ask one question at a time) :
Umbrella post always have series_slug: "My serie slug" in front
matter.
Serie's posts always have series: "My serie slug" in front
matter, and this must be strictly equal to umbrella page series_slug. (eg : you have a post with published: false and series: "SQL Zoology" that will not appear in SQL Zoo serie if you publish it.)
In _layouts/post.html remove {% include series.html %}.
In _includes/post-series.html replace all your code by the following :
{% comment %} #### On an umbrella page {% endcomment %}
{% if page.series_slug != nil %}
{% assign key = page.series_slug %}
{% assign title = page.title %}
{% assign url = page.url %}
{% assign sentence = "All posts in this serie :" %}
{% endif %}
{% comment %} #### On a serie page {% endcomment %}
{% if page.series != nil %}
{% assign key = page.series %}
{% assign umbrella_page = site.posts | where: 'series_slug', key | first %}
{% assign title = umbrella_page.title %}
{% assign url = umbrella_page.url %}
{% assign series_posts = site.posts | where: "series", key %}
{% for post in series_posts %}
{% if post.url == page.url %}
{% assign idx = forloop.index %}
{% endif %}
{% endfor %}
{% capture sentence %}
This article is <strong>Part {{ idx }}</strong> in a <strong>{{ series_posts.size }}-Part</strong> in {{ title }} serie
{% endcapture %}
{% endif %}
{% if page.series_slug != nil or page.series != nil %}
{% assign series_posts = site.posts | where: "series", key %}
<hr />
<div class="panel">
<div class="panel-body">
{% if page.series_slug != nil %}
{% assign key = page.series_slug %}
{% assign title = page.title %}
{% assign url = page.url %}
{% endif %}
<h4>{{ sentence }}</h4>
<ul id="post-series-list">
{% for post in series_posts %}
<li>
{% if page.url == post.url %}
This post : {{ post.title }} - part {{ forloop.index }}
{% else %}
{{ post.title }} - part {{ forloop.index }}
{% endif %}
</li>
{% endfor %}
</ul>
</div>
</div>
{% endif %}
The problem you are facing
You forgot to add the series and series_slug YML variables. That is why it is not working in your case. You seem to not fully understand how the code works, probably due to the complexity of the solution. Therefore, I added another (much simpler) solution, that might fit your needs equally well.
A better/simpler solution
Simply add a YML variable called group: groupname to each post you want in a group. Do NOT skip any of the posts during pagination. Next, list the posts with the same group on the footer of each post (in your page/post layout) with the code below. Finally, add 'part 1', 'part 2', etc. to the post names in the series.
{% if post.group != nil %}
<ul>
{% for post in site.posts %}
{% if post.group == page.group %}
<li>{{ post.title }}</li>
{% endif %}
{% endfor %}
</ul>
{% endif %}
PS. If you really want to skip some posts in the pagination, I would create an universal solution. Add a skip_pagination boolean to the Front Matter (YML) and see if it is true in the pagination loop. This enables you to skip any post in the paginator.
I'm trying to get and display some theme settings which gets the site name and applies to end which i have setup in the schema but cant get it to display the settings.
In the promo_header.liquid snippet file i have:
{% capture promo_header_text_1 %} locale_promo_1_text_{{ shop.name }} {% endcapture %}
{% capture promo_header_url_1 %} locale_promo_1_url_{{ shop.name }} {% endcapture %}
{% capture promo_header_text_2 %} locale_promo_2_text_{{ shop.name }} {% endcapture %}
{% capture promo_header_url_2 %} locale_promo_2_url_{{ shop.name }} {% endcapture %}
<p>
{% if settings[promo_header_text_1] %}
{{ settings[promo_header_text_1] }}
{% endif %}
{% if settings[promo_header_text_2] %}
<span>/</span>{{ settings[promo_header_text_2] }}
{% endif %}
</p>
I have also tried to output using just for example
{{ settings.promo_header_text_1 }}
But not displaying anything either... when i debug and display for example
{{ promo_header_text_1 }}
It does return
locale_promo_1_text_website-test2
Which is correct and in the schema settings file (example based on that one above it is matching and is set in theme customisation)
{
"type": "text",
"id": "locale_promo_1_text_website-test2",
"label": "Promo 1 Text",
"default": "FREE US SHIPPING OVER $35"
}
What am I doing wrong?
For anyone else that might come across the same issue here is the solution I got working:
{% assign promo_header_text_1 = 'locale_promo_1_text_' | append:shop.name %}
and to output
{{ settings[promo_header_text_1] }}
I have a JSON file with the following structure:
{
"resources": [
{
"date": "Nov 7",
"content": [
{
"articleTitle":"The Distribution of Users’ Computer Skills: Worse Than You Think",
"articleUrl":"https://www.nngroup.com/articles/computer-skill-levels/?ref=boomkrak",
"articleAuthor": "Jakob Nielson",
"articleTag": "ux, web design"
},
{
"articleTitle":"How to Use Animation to Improve UX",
"articleUrl":"https://uxplanet.org/how-to-use-animation-to-improve-ux-338819e93bdb#.84b3m022s?ref=boomkrak",
"articleAuthor": "Nick Babich",
"articleTag": "ux, animation"
}
]
},
{
"date": "Nov 15",
"content": [
{
"articleTitle":" 7 Things Every Designer Needs to Know about Accessibility",
"articleUrl":"https://medium.com/salesforce-ux/7-things-every-designer-needs-to-know-about-accessibility-64f105f0881b#.5pgg5014x?ref=boomkrak",
"articleAuthor": "Jesse Hausler",
"articleTag": "ux, web design, accessibility"
},
{
"articleTitle":"Get the most out of your research with storytelling",
"articleUrl":"https://blog.intercom.com/get-the-most-out-of-your-research-storytelling/?ref=boomkrak",
"articleAuthor": "Jillian Wells",
"articleTag": "design research, collaboration"
}
]
}
]
}
I want to show the article based on each tag. For example, if I want to show ux articles, then all articles with ux tag should be displayed.
Anyone know how to do it in Jekyll?
Considering that your datas are in _datas/articles.json, you can use this include file (_includes/listbyTag.html) :
{% assign tag = include.tag %}
{% assign days = site.data.articles.resources %}
{% assign list = ""| split: "/" %} {% comment %} creates an empty array {% endcomment %}
{% for day in days %}
{% for article in day.content %}
{% if article.articleTag contains tag %}
{% assign list = list | push: article %}
{% endif %}
{% endfor %}
{% endfor %}
{% if list.size != 0 %}
<h3>Found {{ list.size }} posts for tag : {{ tag }}</h3>
<ul>
{% for post in list %}
<li>{{ post.articleTitle }}</li>
{% endfor %}
</ul>
{% endif %}
Now you can include it anywhere with :
{% include listByTag.html tag="ux" %}
Or for a tag page :
---
tag: ux
title: my title
layout: default
---
{% include listByTag.html tag=page.tag %}
I have a json:
var json = [{
a: "asdf",
b: "a",
c: {1:{z:30,x:20,y:50},2:{z:30,x:50,y:30}}
},
{
a: "fdsa",
b: "o",
c: {1:{z:10,x:20,y:50},2:{z:0,x:20,y:30}}
}
]
I want to have a condition to check:
if any item z, x, or y in the c object is greater than 30, show the value for a
Is this possible? I did some research but couldn't find any answers.
Please help! Thanks!
I tried
{% for c,b in json.c %}
Your use case is incredibly complex and probably better done server-side, but here's a way you can do it in swig...
{% for item in json %}
{% set show = false %}
{% for set in item.c %}
{% for k in set %}
{% if k > 30 %}
{% set show = true %}
{% endif %}
{% endfor %}
{% endfor %}
{% if show %}
{{ item.a }}
{% endif %}
{% endfor %}