Index value in for loop with Twig - twig

I'd like to store the iteration value to use in data-target so it would be #question0, #quesion1, #question2 and so on...
I tried using {{item.id}} but this didn't work.
{% for item in post.get_field('qanda') %}
<div class="panel panel-default">
<div class="panel-heading accordion-toggle question-toggle collapsed"
data-parent="#faqAccordion" data-target="#question{{item.id}}"
data-toggle="collapse">
<h4 class="panel-title"><a class="ing">Q:
{{item.question}}</a></h4>
</div>
<div class="panel-collapse collapse" id="question{{item.id}}" style=
"height: 0px;">
<div class="panel-body">
{{item.answer}}
</div>
</div>{% endfor %}
</div>

You can use the variable loop.index0 (for zero based indexing).
data-target="#question{{loop.index0}}"
should do what you want. See the for loop documentation for more info for more information.

Related

In Django website even if I add an item by pressing add to cart button the status of True for the product added is not shown and still false is visibl

I have made a django e-comm website , when I press the add to cart button on my home page I have written a function which should change the status of a product from false to true once it is added in the cart but it does not work
I have given my cart.py and index.html code
Thank you
cart.py
from django import template
register = template.Library()
#register.filter(name='is_in_cart')
def is_in_cart(product,cart):
keys = cart.keys()
for id in keys:
print(id , product.id)
if int(id) == product.id:
return True
return False
index.html
{% extends 'main/base.html'%}
{% block title %}
index
{% endblock %}
{% block content %}
{% load cart %}
<div class="container-fluid">
<div class="row">
<div class="col-lg-3">
<div class="list-group mt-3">
{% for items in category %}
{{items.Category_name}} <!--i first used a small c for category but it did not pick the words from my category.py fle-->
{% endfor %}
</div>
</div>
<div class="col-lg-9">
<div class="row">
{% for items in product %}
<div class="card mx-auto mb-3 mt-3" style="width: 18rem;">
<img class="card-img-top" src="{{items.product_image.url}}" alt="Card image cap">
<div class="card-body">
<h5 class="card-title">{{items.product_name}}</h5>
<p class="card-text"><b>{{items.product_price}}</b></p>
<p class="card-text"><b>{{items.product_detail}}</b></p>
{{product | is_in_cart:request.session.cart }}
<form action="/" mthod="POST">
{% csrf_token %}
<input hidden type="text" name='product' value='{{items.id}}'>
<input href="#" type="submit" class="float-right btn btn-light border btn-sm" value="Add to Cart">
</form>
</div>
</div>
{% endfor %}
</div>
</div>
</div>
</div>
{% endblock %}

How add space between two cards - bootstrap?

I was creating a simple blog page using Django. When I added cards for the articles it came like this
There is no space between the cards.
{% extends 'base.html' %}
{% block content %}
<div class="card mt-3" style="width: 100%;">
{% for post in posts %}
<div class="card-header">
<cite title="Source Title">{{ post.author }}</cite>
<small class="text-muted float-right">{{ post.date_posted | date:"F d, Y" }}</small>
</div>
<div class="card-body">
<div class="card-title">{{ post.title }}</div>
<p class="card-text">{{ post.content }}</p>
</div>
{% endfor %}
</div>
{% endblock content %}
How do I add space between these cards?
your for loop is not in correct place change code from
{% extends 'base.html' %}
{% block content %}
<div class="card mt-3" style="width: 100%;">
{% for post in posts %}
<div class="card-header">
<cite title="Source Title">{{ post.author }}</cite>
<small class="text-muted float-right">{{ post.date_posted | date:"F d, Y" }}</small>
</div>
<div class="card-body">
<div class="card-title">{{ post.title }}</div>
<p class="card-text">{{ post.content }}</p>
</div>
{% endfor %}
</div>
{% endblock content %}
to bellow code
{% extends 'base.html' %}
{% block content %}
{% for post in posts %}
<div class="card mt-3" style="width: 100%;">
<div class="card-header">
<cite title="Source Title">{{ post.author }}</cite>
<small class="text-muted float-right">{{ post.date_posted | date:"F d, Y" }}</small>
</div>
<div class="card-body">
<div class="card-title">{{ post.title }}</div>
<p class="card-text">{{ post.content }}</p>
</div>
</div>
{% endfor %}
{% endblock content %}
Firstly, you need to do the loop for every card, instead of doing it for the inner divs 'card-header' and 'card-body'. Secondly, to answer you question, you should use a spacing by either a margin or a padding.
I would suggest to make the cards a standard width and use a 'margin right 3':
{% for post in posts %}
<div class="card mt-3 mr-3" style="width: 250px">
<div class="card-header">
...
</div>
<div class="card-body">
...
</div>
</div>
{% endfor %}
Besides this solution, I suggest you read the Bootstaps Grid Layout documentation, so you can place the cards nicely within your content block.

twig: take an api and print it in html

i am using grav, and with twig i have an html file like this:
<div class="singlePostContainer">
<span class="postNumber">
01
</span>
<div class="postTextContainer">
<div class="postTitle">
title
</div>
<div class="postDate">
date
</div>
<div class="postAuthor">
author
</div>
</div>
</div>
then I have this API: https://5efc440acf235d0016ad72be.mockapi.io/api/floating-point/floating-point
I want to take the data from that api (date, author etc) and print it inside the corresponding html div
Fetch the data and transform the JSON to an array, then pass it to your view, e.g.
$api_data = json_decode(file_get_contents('https://5efc440acf235d0016ad72be.mockapi.io/api/floating-point/floating-point'), true);
<div class="postTextContainer">
<div class="postTitle">title</div>
<div class="postDate">date</div>
<div class="postAuthor">author</div>
</div>
{% for row in api_data %}
<div class="postTextContainer">
<div class="postTitle">{{ row.title }}</div>
<div class="postDate">{{ row.date }}</div>
<div class="postAuthor">{{ row.author }}</div>
</div>
{% endfor %}

how to get to the next element of list inside for loop in django template?

i have a list like
lst = [
['img1','img2','img3','img4','img5'],
['img6','img7','img8','img9']
]
and a template like
<div class="row"> -- 1st row
<div class="col-lg-3" data-aos="fade-up"> --col-lg-3
<a href="{{img1}}"> --img1
<img src="{{img1}}"> -- img1
</a>
</div>
<div class="col-lg-6" data-aos="fade-up" data-aos-delay="100"> --col-lg-6
<a href="{{img2}}"> --img2
<img src="{{img2}}"> --img2
</a>
</div>
<div class="col-lg-3" data-aos="fade-up" data-aos-delay="200"> --col-lg-3
<a href="{{img}}"> --img3
<img src="{{img}}"> --img3
</a>
</div>
</div>
<div class="row"> ---2nd row
<div class="col-lg-8" data-aos="fade-up" data-aos-delay="100"> --col-lg-8
<a href="{{img2}}"> --img2
<img src="{{img2}}"> --img2
</a>
</div>
<div class="col-lg-4" data-aos="fade-up" data-aos-delay="200"> --col-lg-4
<a href="{{img}}"> --img3
<img src="{{img}}"> --img3
</a>
</div>
</div>
please note few things:
every col-lg size is of different size
every and tag of a column contain 1 img
i want to iterate over the whole template but in a different way
eg: i can do this in python where i can iterator over list and assign the value as well
for data in lst:
it = iter(data)
print (next(it)) ---where print will be replaced with img tag
print (next(it))
print (next(it))
print (next(it))
print (next(it))
but how can i do this in django template
Django's for-in template loop builds the DOM defined between the template tag loop for each item in data.
That being said, you could adapt your solution like so:
<div class="row align-items-stretch">
{% for img in data %}
<div class="col-6 col-md-6 col-lg-3" data-aos="fade-up">
<a href="{{ data.img }}" class="d-block photo-item" data-fancybox="gallery">
<img src="{{ data.img.url }}" alt="Image" class="img-fluid">
<div class="photo-text-more">
<span class="icon icon-camera"></span>
</div>
</a>
</div>
{% endfor %}
</div>
If data contains three items/images, the output will be something like:
<div class="row align-items-stretch">
# 1st iteration
<div class="col-6 col-md-6 col-lg-3" data-aos="fade-up">
<a href="href_according_to_data" class="d-block photo-item" data-fancybox="gallery">
<img src="link" alt="Image" class="img-fluid">
<div class="photo-text-more">
<span class="icon icon-camera"></span>
</div>
</a>
</div>
# 2nd iteration
<div class="col-6 col-md-6 col-lg-3" data-aos="fade-up">
<a href="href_according_to_data" class="d-block photo-item" data-fancybox="gallery">
<img src="link" alt="Image" class="img-fluid">
<div class="photo-text-more">
<span class="icon icon-camera"></span>
</div>
</a>
</div>
# 3rd iteration
<div class="col-6 col-md-6 col-lg-3" data-aos="fade-up">
<a href="href_according_to_data" class="d-block photo-item" data-fancybox="gallery">
<img src="link" alt="Image" class="img-fluid">
<div class="photo-text-more">
<span class="icon icon-camera"></span>
</div>
</a>
</div>
</div>

Why generating pagination links raises 'Call to undefined method'?

I've got an problem. This is my first time using pagination.
This is my view:
#extends('base')
#section('title', 'News')
#stop
#section('main')
#if ($news->count())
#foreach($news as $news)
<div class="container">
<div class="doc-content-box">
<legend>{{ $news->title }} <div id="spaceholder"></div>
<p>
<h6><span class="muted"><i class="icon-calendar"></i> {{ $news->created_at }} {{ $news->author }}<span>
</p>
</h6>
</legend>
<div style="margin-top:7px">
<p>{{ $news->content }}</p>
</div>
<div class="btn-group">
<a class="btn btn-primary" href="{{ URL::route('news.edit', $news->id) }}"><i class="icon-pencil"></i> Edit</a>
<a class="btn btn-danger" href="{{ URL::route('news.destroy', $news->id) }}"><i class="icon-trash icon-large"></i> Delete</a>
</div>
</div> <!-- /container -->
<div id="spaceholder"> </div>
#endforeach
{{ $news->links() }}
#else
<div class="container">
<div class="doc-content-box">
<legend>News</legend>
<p>There are no news.<br /><br />If you wish to create a news, you should go to our news management page!</p>
</div>
</div>
#endif
#stop
Then it results into an error Call to undefined method Illuminate\Database\Query\Builder::links().
I've also tried changing #foreach($news as $news) to #foreach($news->results as $news), but then I get an new error:
Undefined property: Illuminate\Pagination\Paginator::$results
The paginator itself works, but the pagination links (next and previous) won't work.
This happens when your query has not been executed. Your variable $news is a query builder not an array of objects. Before calling:
$news->links();
You need to execute your query by calling:
$news = $news->get();
Then after calling the get() method it will return an array representing the result set instead of an instance of Illuminate\Database\Query\Builder.
Note: when you do a foreach in a instance of Illuminate\Database\Query\Builder it will execute the query but the results will be scoped inside the foreach loop. That's the reason that you cannot retrieve the pagination links, because the object you are referencing is the query instead of the results.
If you test that code :
#foreach($news as $new)
<div class="container">
<div class="doc-content-box">
<legend>{{ $new->title }} <div id="spaceholder"></div>
<p>
<h6><span class="muted"><i class="icon-calendar"></i> {{ $new->created_at }} {{ $new->author }}<span>
</p>
</h6>
</legend>
<div style="margin-top:7px">
<p>{{ $new->content }}</p>
</div>
<div class="btn-group">
<a class="btn btn-primary" href="{{ URL::route('news.edit', $new->id) }}"><i class="icon-pencil"></i> Edit</a>
<a class="btn btn-danger" href="{{ URL::route('news.destroy', $new->id) }}"><i class="icon-trash icon-large"></i> Delete</a>
</div>
</div> <!-- /container -->
<div id="spaceholder"> </div>
#endforeach

Resources