Modify Django for loop every four iterations - css

I have a calendar generated by Django and styled with Bootstrap.
Here is the code in the Django template :
<div class="content">
{% for month in period.get_months %}
<div class="col-md-3">
<div class="row row-centered">
<button class="btn btn-custom active" href="{% url "month_calendar" calendar.slug %}{% querystring_for_date month.start 2 %}">{{month.name}}</button>
</div>
<div>
{% month_table calendar month "small" %}
</div>
</div>
{% endfor %}
</div>
Now, since months have a different number of weeks they have different heights I would like to avoid something like this:
I understand from this answer that the best solution would be to use a clearfix.
So, how can I modify the for loop in my template so that Django inserts an extra line <div class="clearfix"></div> every four items?

Django templates for loop store current index in forloop.counter variable. You can read about this in docs. So you can try to change you code like this:
<div class="content">
{% for month in period.get_months %}
<div class="col-md-3">
<div class="row row-centered">
<button class="btn btn-custom active" href="{% url "month_calendar" calendar.slug %}{% querystring_for_date month.start 2 %}">{{month.name}}</button>
</div>
<div>
{% month_table calendar month "small" %}
</div>
</div>
{% if forloop.counter|divisibleby:4 %}
<div class="clearfix"></div>
{% endif %}
{% endfor %}
</div>

Related

Bootstrap5 Mobile Friendly Web

I am working on a web app and need it to be compatible with mobile devices.
The web app is written using Django, I am using Bootstrap 5 for arranging the page to be responsive. I am totally a newbie with mobile frontend development.
Now I understand that the grid system could help us scale the whole page to fit mobile devices properly. But as the page is developed using desktop, when viewing in mobile devices, the elements in the page is so small. I was originally thinking that Bootstrap would magically enlarge each row when it scale to fit mobile devices, but that's not the case.
Consulting with my friends, we seem to need to manually set size (width * height) based on the device-width. Then that's a lot of work. Is this the only way to go?
The page does scale to fit mobile devices, but each card is so small that it is very difficult to see the text/button.
<head>
<title>.....</title>
<meta charset="utf-8">
<meta name="viewpoint" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.1/dist/css/bootstrap.min.css" rel="stylesheet">
<link href='https://fonts.googleapis.com/css?family=Sofia' rel='stylesheet'>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.2.1/dist/js/bootstrap.bundle.min.js"></script>
</head>
<body class="container-lg pt-1">
<div class="Heading .text-center">
<div class="row">
<h1 class="col-sm-12">Title Here</h1>
</div>
</div>
<div data-bs-spy="scroll" data-bs-target=".navbar" data-bs-offset="50">
<nav class="navbar navbar-expand-sm justify-content-center sticky-top">
<ul class="navbar-nav">
{% for categ in categories_list %}
<li><a class="nav-link" href="#{{categ.split|join:'-'}}"> {{categ}}</a></li>
{% endfor %}
</ul>
</nav>
{% for categ in categories_list %} {% with entrees=foods_by_categ|get_item:categ %}
<div id="{{categ.split|join:'-'}}">
<h3>{{categ|capfirst}}</h3>
{% for entree in entrees %}
<div class="card">
<div class="card-header">
{{entree.name}}
<button data-bs-toggle="modal" data-bs-target="#food-{{entree.id}}" class="btn float-end">Add to Cart</button>
</div>
{% if entree.description %}
<div class="card-body">
<pre>{{entree.description}}</pre>
</div>
{% endif %}
<form id="food-{{entree.id}}" action="{% url 'cart:add2cart' %}" class="card-body modal fade" method="post">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
{% with add2cart_form=add2cart_forms|get_item:entree.name %} {% csrf_token %} {{ add2cart_form.non_field_errors }}
<div class="modal-header">
<h4 class="modal-title">{{entree.name}}</h4>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<ul class="list-group list-group-flush">
{% if entree.small_available %}
<li class="list-group-item">
{{ add2cart_form.size_opt.errors }} {{ add2cart_form.size_opt.label_tag}} {{ add2cart_form.size_opt }}
</li>
{% endif %}
<li class="list-group-item">
<button type="submit" class="btn btn-primary float-end">Add</button>
</li>
</ul>
</div>
{% endwith %}
</div>
</div>
</form>
</div>
{% endfor %}
</div>
{% endwith %} {% endfor %}
</div>
</body>

Twig Wordpress Repeater within a repeater

I would like to ask for help regarding a repeater within a repeater on Wordpress using Twig. The Services section shows up correctly but the Features section within the Services section isn't showing up.
Here is a screenshot of the Wordpress ACF.Click Me
And right below is the code that I am currently using.
Please advise. Thank you!
{% extends "page.twig" %}
{% block additional %}
<div id="page-services">
<section id="services">
<div class="row small-up-1 large-up-1">
<div class="small-12 medium-11 large-9 columns small-centered">
<div class="services-grid animated fadeIn wow">
<p align="center">
{{post.services_desc}}
</p>
</div>
</div>
</div>
<div class="line centered"></div>
</div>
<center>
<div class="row">
<div class="small-12 medium-11 large-9 columns small-centered">
<div class="features-header animated fadeIn wow">
{% for item in post.get_field('services_ist') %}
<div class="column services">
<h2 class="capitalize bold">
{{item.services_title}}
</h2>
{% if item.services_subtitle %}
<h4 class="subtitle">
{{item.services_subtitle}}
</h4>
<div class="line thin"></div>
{% endif %}
{% if item.services_content %}
<div class="description">
{{item.services_content}}
<br><br>
</div>
{% endif %}
{% if feats.services_feat %}
{% for feats in post.get_field('services_feat') %}
<p>{{feats.feat_title}}</p>
{% endfor %}
{% if feats.feats_desc %}
<h4 class="feats description">
{{feats.feats_desc}}
</h4>
{% endif %}
{% endif %}
</div>
{% endfor %}
</center>
</div>
</div>
</div>
</section>
</div>
{% endblock %}
As the ACF Integration Guide says, you shouldn’t use get_field() again when you try to access nested repeater fields:
When you run get_field on an outer ACF field, everything inside is ready to be traversed. You can refer to nested fields via item_outer.inner_repeater
So instead of using:
{% for feats in post.get_field('services_feat') %}
You should use:
{% if feats.services_feat %}
{% for feats in feats.services_feat %}
<p>{{ feats.feat_title }}</p>
{% endfor %}
{# … #}
{% endif %}
I have never done twig before but a quick search got me something.
Change the inner repeater to this:
{% for feats in services_ist.get_field('services_feat') %}
<p>{{feats.feat_title}}</p>
{% endfor %}
This way the second repeater knows that its a child from the first repeater instead of a direct child to the post.

Changing the background-color of a jumbotron from bootstrap in django

I am very new to web development and Django. I am following a tutorial called "Try Django 1.8".
In this code I am supposed to change the background-color of jumbotron to #155A1E.
If I press shift + refresh in google chrome, the color shows up then it changes back to gray. When I inspect the code in google chrome, I can see in the styles tab that the background-color in the .jumbotron{} has a strike-through. Also there is another verion of .jumbotron{} in the styles tab that has a background-color and has a check. If I uncheck the box, the color gets fixed.
How can I fix this in Django?
{% extends "base.html" %}
{% load crispy_forms_tags %}
{% block head_title %}Welcome | {{ block.super}}{% endblock %}
<style>
{% block style %}
.jumbotron {
background-color: #155A1E;
}
{% endblock %}
</style>
{% block jumbotron %}
<div class="jumbotron">
<div class='container'>
<div class="row">
<div class='col-sm-6'>
<h1>Try Django 1.8</h1>
<p>Some text here!!! This text should be long so that we can test the columns in the webpage. So here we go. We are trying to make this line as long as possible.</p>
<p>
<a class="btn btn-lg btn-primary" href="" role="button">Join us »</a>
</p>
</div>
<div class='col-sm-6' style="background-color:black;height:300px">
</div>
</div>
</div>
</div>
{% endblock %}
{% block content %}
<div class="row">
<div class="row">
</div>
<div class="col-xs-3 pull-right">
<p class='lead text-align-center'>{{ title}}</p>
<!--{{ user }}-->
<!--<!–{{ request.user }}–>-->
<!--abc is = {{ abc }}-->
<form method='POST' action=''>{% csrf_token %}
{{ form|crispy }}
<input class='btn btn-primary' type="submit" value="Signup" />
</form>
</div>
<div class='col-sm-3'>
<p class='lead text-align-center'>Built with Django & Bootstrap</p>
</div>
<div class='col-sm-3'>
<p class='lead text-align-center'>created for starters of all kinds.</p>
</div>
<div class='col-sm-3'>
<p class='lead text-align-center'>Always open source.</p>
</div>
</div>
{% endblock %}
You can add do important to your css attribute.
Just like that:
.jumbotron {
background-color: #155A1E!important;
}
It will be taken instead of the default one
It may be very late to answer the question but could help someone who is doing the tutorial now as myself.
Problem is your style should come under the
{% block jumbotron %}
otherwise its never been executed.
Here it is
{% block jumbotron %}
<style>
{% block style %}
.jumbotron {
background-color : #1e78d2 !important;
}
{% endblock %}
</style>
<div class="jumbotron">
<div class="container">....... {% endblock %}
Hope it helps someone
Makesure source of bootstrap is before your style source, and example:
<link href="{% static 'css/bootstrap.min.css' %}" rel="stylesheet" media="all">
<link href="{% static 'css/your_style.css' %}" rel="stylesheet" media="all">

Twig for loop put every 1 element in a new container

How to render like this with its own unique class name on every loop
{% for row in rows %}
{{ row.content }}
{% endfor %}
<div class="item1"> Item 1 </div>
<div class="item2"> Item 2 </div>
<div class="item3"> Item 3 </div>
<div class="item4"> Item 4 </div>
and so on how do can i achieve this, Please help thanks.
or is there an other way where i can call each element in the for loop individually ???
You can use loop.index:
{% for row in rows %}
<div class="item{{ loop.index }}">{{ row.content }}</div>
{% endfor %}

How to handle twig view and bootstrap 3 rows/columns?

I have an Article entity and I made a findAll() in the controller.
I rendered each article in a div with the col-md-6 class.
But foreach 2 articles I must wrap these divs in a row div.
How can I do this with twig ?
Thanks.
EDIT :
I tried your code (NHG) like this:
{% for article in articles %}
{% if loop.index % 2 == 0 %}
<div class="row"></div>
{% endif %}
<div class="col-md-6">
<article class="well well-sm">
<img src="{{ article.image }}" alt="{{ article.title }}" class="img-thumbnail">
<h2 class="h3 text-center">{{ article.title }}</h2>
<div class="alert alert-success well-sm">
{{ article.content|striptags|slice(0, 235) }}...
</div>
<a class="btn btn-default btn-sm pull-right" href="#">{{ article.comments|length }} Comments</a>
<div class="btn-group btn-group-sm">
{% for tag in article.tags %}
<a class="btn btn-default">{{ tag.name }}</a>
{% endfor %}
</div>
</article>
</div>
{% endfor %}
But it doesn't work.
I want to have something like this :
<div class="row">
<div class="col-md-6"></div>
<div class="col-md-6"></div>
</div>
<div class="row">
<div class="col-md-6"></div>
<div class="col-md-6"></div>
</div>
<div class="row">
<div class="col-md-6"></div>
<div class="col-md-6"></div>
</div>
UPDATED:
As #Maerlyn suggested:
{% for row in articles|batch(2) %}
<div class="row">
{% for article in row %}
<div class="col-md-6">
// your content
</div>
{% endfor %}
</div>
{% endfor %}
OLD way:
Use loop.index (doc: The loop variable), modulo (doc: Math operators) and if (doc: if statement )
{% for article in articles %}
{% if loop.index % 2 == 1 %}
<div class="row">
{% endif %}
<div class="col-md-6">
// your content
</div>
{% if (loop.index % 2 == 0 or loop.last) %}
</div>
{% endif %}
{% endfor %}
{% for row in articles|batch(2) %}
<div class="row">
{% for article in row %}
<div class="col-md-6">
// your content
{% if loop.index is divisibleby(3) %}
</div>
{% endif %}
{% endfor %}
</div>
{% endfor %}
I suggest :
<div class="row">
{% for article in articles %}
{% if (loop.index0 % 2 == 0) and not loop.first %}
</div>
<div class="row">
{% endif %}
<div class="col-xs-12 col-sm-6 col-md-6 col-lg-6">
// your content
</div>
{% endfor %}
</div>

Resources