I am currently working on a django blog. However, I am experiencing some difficulties with the size of the post thumbnails. Here's a picture:
What I marked in yellow is how the image should be filling the space. The width is fine, but the heigh isn't working well as you can see.
Here's the code:
{% extends 'base.html' %}
{% load static %}
{% block content %}
<style>
img {
height: 100%;
width: 100%;
}
</style>
<!-- Post-->
{% for obj in object_list %}
<div class="row d-flex align-items-stretch">
{% if not forloop.first and not forloop.last %}
<div class="image col-lg-5"><img src="{{ obj.thumbnail.url }}" alt="..."></div> #Here's the image
{% endif %}
<div class="text col-lg-7">
<div class="text-inner d-flex align-items-center">
<div class="content">
<header class="post-header">
<div class="category">
{% for cat in obj.categories.all %}
{{ cat }}
{% endfor %}
</div>
<a href="{{ obj.get_absolute_url }}">
<h2 class="h4">{{ obj.title }}</h2>
</a>
</header>
<p>{{ obj.overview|linebreaks|truncatechars:200 }}</p>
<footer class="post-footer d-flex align-items-center"><a href="#" class="author d-flex align-items-center flex-wrap">
<div class="avatar"><img src="{{ obj.author.profile_picture.url }}" alt="..." class="img-fluid"></div>
<div class="title"><span>{{ obj.author }}</span></div></a>
<div class="date"><i class="icon-clock"></i> {{ obj.timestamp|timesince }} ago</div>
<div class="comments"><i class="icon-comment"></i>{{ obj.comment_count }}</div>
</footer>
</div>
</div>
</div>
{% if forloop.first or forloop.last %}
<div class="image col-lg-5"><img src="{{ obj.thumbnail.url }}" alt="..."></div> #Here's the image
{% endif %}
</div>
{% endfor %}
</div>
</section>
I have no idea where the error is. I've tried to debug the problem but I haven been able to debug it
The way I see it, it's doing exactly what it's supposed to.
You put the image inside a column, then the image has 100% of the width, and because this is just an image inside a div (no display flex on the column or tricks involved), 100% height is just not gonna work and the default height of the image is used.
And even if it did work, and the images where 100% both on height and width, they'll probably end up all stretched and deformed in different resolutions, because the ratio of width:height probably changes.
I usually skip this dilemma by avoiding the use of the img tag altogether, and setting the images as background-images in the column with the 'image' class. Then set the background-size to "cover", and background-position to "center". You probably also need to set a minimum height for this column, so the images don't completely disappear when the columns stack on top of each other on smaller screens.
You can add a class like
<style>
.image {
background-size: cover;
background-repeat: no-repeat;
background-position: center;
min-height: 200px; // this size is arbitrary, choose what suits best
}
</style>
And then add the image on the iteration like so
<div class="image col-lg-5" style="background-image: url('{{ obj.thumbnail.url }}');"></div>
first you install it using pip install easy-thumbnails
INSTALLED_APPS = [
# ...
'easy_thumbnails',
]
then you do your migrations,and use it in your templates, this is from a project of mine:
{% load thumbnail %}
{% for image in images %}
<div class="image">
<a href="{{ image.get_absolute_url }}">
{% thumbnail image.image 300x300 crop="smart" as im %}
<a href="{{ image.get_absolute_url }}">
<img src="{{ im.url }}">
</a>
</a>
</div>
{% endfor %}
you can play with the details 300x300 as you wish, also the crop is optional but very useful
if you have trouble showing images add : THUMBNAIL_DEBUG = True to your settings
here is the docs https://easy-thumbnails.readthedocs.io/en/
Related
I am working on a simple web-application with flask and am currently trying to dynamically create a scrollspy list group with jinja. In the code snippet the variable "choices" represents a list of lists of dictionaries. So the variable dict will be a list of dictionaries that populates the ids needed for the list group to work. For simplicity, I am testing it with choices containing only one list of dictionaries and loop.index to create the ids, but I was going to change that to uniquly generated ids later as choices will have more elements.
Unfortunately, the list group does not work properly. Any ideas as to what I'm doing wrong? The browser console throws me an error, "uncaught TypeError: i is null", relating to the bootstrap scrollspy.js. I was not able to trace it back and figure out what causes the error.
{% extends "layout.html" %}
{% block title %}
Results
{% endblock %}
{% block main %}
<!--course display-->
{% for i in choices %}
<div class= "container-fluid">
<div class="row justify-content-center">
<div class="col-9 heading">
<div>
<h1>Coursera Courses</h1>
</div>
</div>
</div>
<div class="row justify-content-center result-background">
<div id="list-example" class="col-2 list-group">
{% for dict in i%}
<a class="list-group-item list-group-item-dark list-group-item-action" href="#list-item-{{ loop.index }}">{{ dict["Course Name"] }}</a>
{% endfor %}
</div>
<div class="col-7">
<div class="scrollspy-example" data-bs-spy="scroll" data-bs-target="#list-example" data-bs-offset="40" tabindex="0">
{% for dict in i %}
<div class="boxlayout" id="#list-item-{{ loop.index }}">
<img src="{{ dict["Image URL"] }}" alt="responsive webite" class="img-thumbnail" align="left" width="15%" height="15%">
<h2>{{ dict["Course Name"] }}</h2>
<details close>
<summary>Lorem ipsum</summary>
Lorem ipsum
</details>
</br>
<table>
<tr>
<td>Manufacturer</td><td> </td>
<tr>
<td>Certificate</td><td>{{ dict["Certificate"] }}</td>
</tr>
<tr>
<td>Costs</td><td>${{ dict["Current Price"] }}</td>
</tr>
<tr>
<td>Landing Page</td>
</tr>
</table>
</div>
{% endfor %}
</div>
</div>
</div>
</div>
{% endfor %}
{% endblock %}
The CSS I use as per the Bootstrap requirements:
.scrollspy-example{
position: relative;
overflow-y: scroll;
height: 300px;
}
I am using the code in my index.html file.
{% for post in blog_posts.items %}
<div class="col-sm-6">
<div class="card" >
<div class="card-body">
<h2><a class="card-title" href=" {{ url_for('blog_posts.blog_post', blog_post_id=post.id) }}">{{ post.title }}</a></h2>
Written By: {{ post.author.username }}
<p>Published on: {{ post.date.strftime('%Y-%m-%d') }}</p>
<p class="card-text">{{ post.text[:100] }}...</p>
Read Blog Post
</div>
</div>
</div>
{% endfor %}
My understanding from bootstrap is that it would create a 6 column grid, however it is just stacking one card below the next. I am sure it is something I am missing. Thank you for your help.
You probably need to use a card deck or card group to achieve this:
I'd lose this div:
<div class="col-sm-6">
Then put the for loop within a card-group div:
<div class='card-group'>
{% for post in blog_posts.items %}
<div class="card" >
<div class="card-body">
...
</div>
</div>
{% endfor %}
</div>
If you want some spacing between the cards, you can change the class of the outer div to card-deck.
See the Card docs for more options.
.col-sm-6{ display: flex } add this css property to the parent that contains all cards.
alternatively you can use floats .col-sm-6 > .card{ float: left}
I seem to be having trouble to extend my background color for my 2 column layout. The user can add categories so the background color has to be able to adjust with the amount of categories the user wants to add in.
html file:
{% for category in categories %}
<div class="row__2 sub-pages--background">
<div class="sub-pages--categories-background">
<div class="sub-pages--categories">
<a href="{% url 'blogging_logs:topics' category.id %}" class="sub-pages--categories-position ">{{ category }}
<img class="sub-pages--img" src="{{ category.category_image.url }}">
</a>
</div>
</div>
</div>
{% empty %}
<p>No categories entered yet.</p>
{% endfor %}
css file:
&--background {
background-color: $mainBackground;
padding-bottom: 2rem;
}
I feel like it has to do with the way I'm formatting my divs
Since you mentioned in comments that you are using floats, simply add a parent element that will have the background and then add something known as clearfix, at the end of it.
HTML:
<div class="parent--background">
{% for category in categories %}
<div class="row__2 sub-pages--background">
<div class="sub-pages--categories-background">
<div class="sub-pages--categories">
<a href="{% url 'blogging_logs:topics' category.id %}" class="sub-pages--categories-position ">{{ category }}
<img class="sub-pages--img" src="{{ category.category_image.url }}">
</a>
</div>
</div>
</div>
{% empty %}
<p>No categories entered yet.</p>
{% endfor %}
<div class="clearfix"></div>
</div>
CSS:
.clearfix::after {
content: "";
clear: both;
display: table;
}
I am trying to make a gallery of images of unknown number using HTML. I am using bootstrap to display the images and have some django template library coding. I am not able to align the images correctly. I am basically trying to use cycle tag in Django Template to display the row class in bootstrap after every 2 images. I want the images to appear in a row, each row with two images. The height of each image in the row should be aligned correctly. Right now the height is not aligned. One image is slightly higher than the other. Can you please help, this is my html file?
<div class="container">
{% load staticfiles %}
{% for plot in plots%}
{% with plot|add:".png" as image_static %}`
<div class = "{% cycle 'row' '' %}">
<div class = "col-md-5">
<div class = "thumbnail">
<img src="{% static image_static %}" alt="My image"/>
</div>
<div class = "caption">
<h3>Thumbnail label</h3>
<p>Some sample text. Some sample text.</p>
<p>
<a href = "#" class = "btn btn-primary" role = "button">
Button
</a>
<a href = "#" class = "btn btn-default" role = "button">
Button
</a>
</p>
</div>
</div>
{% endwith %}
<br><br><br>
</div>
{% endfor %}
</div>
It cannot be done with cycle! Here's how it could be done instead:
{% for plot in plots%}
{% with plot|add:".png" as image_static %}
<div class='col-md-6'>
<div class = "thumbnail">
<img src="{% static image_static %}" alt="My image"/>
</div>
<!-- ... -->
</div>
{% if forloop.counter|divisibleby:"2" %}
</div>
<div class='row'>
{% endif %}
{% endwith %}
{% endfor %}
So, we close the row div and start a new one whenever the forloop index is divisible by 2, so we'll start a new row every two images!
Sorry this question is unavoidably kind of long.
I have basetemplate.html which other files extend.
basetemplate.html:
<!DOCTYPE html>
<html lang="en">
<head>....</head>
<body>
<nav class="navbar navbar-default navbar-fixed-top">...</nav>
<div class="container">
<div class="row">
<div class="col-md-3 hidden-xs hidden-sm">
{% block profile %}
<p>User details here...</p>
{% endblock %}
</div>
<div class = "col-md-6">
{% block mainBody %}
{% endblock %}
</div>
<div class = "col-md-3 hidden-xs hidden-sm">
{% block others %}
<p>Others here...</p>
{% endblock %}
</div>
</div>
</div>
</body>
</html>
I now have home.html extending basetemplate.html:
home.html:
{% extends "mysite/base.html" %}
{% block mainBody %}
{% include 'mysite/mainbody.html' %}
{% endblock %}
And mainbody.html contains:
{% for article in articles reversed %}
<div class="article-wrapper">
<div class="article-content">
<p>{{ article.content }}</p>
</div>
</div>
{% endfor %}
This works well for home.html. All my articles are displayed within <div class = "col-md-6"></div> but it doesn't for hashtags.html page. If I have, say 10 articles coming for a particular hashtag, it will display two or more within <div class = "col-md-6"></div> and may be three outside it and the rest outside <div class = "row"></div>. And sometimes some are even displayed outside <div class = "container"></div>.
hashtag.html:
{% extends "mysite/base.html" %}
{% block mainBody %}
{% include 'mysite/mainbody.html' %}
{% endblock %}
Query that fetches article for home.html is articles = Article.objects.all()[:10] while that of hashtag.html is articles = Article.objects.filter(content__icontains=hashtaggedword)[:10].
I have checked and checked to see if have any unclosed tag but couldn't find any even after using W3C Validator. I have also checked to see if there is something strange with those that display outside col-md-6 but they are okay and displayed in order of time they are created.
Probably article.content have html tags. Escape them by escape.
{{ article.content|escape }}
try using this way:
<ul class="list-group">
{% for article in articles reversed %}
<li class="list-group-item">{{ article.content }}</li>
{% endfor %}
</ul>
Result of this code is a simple list and you can put this to your column without any problem