My all pages are inheriting from base.html file. However I want my about page to be slightly different.
Majority of the pages are having
<main role="main" class="container">
<div class="row">
<div class="col-md-8">
<div>
{% if messages %}
{% for message in messages %}
<div class="alert alert-{{ message.tags }}">
{{ message }}
</div>
{% endfor %}
{% endif %}
{% block content %}{% endblock %}
</div>
<div class="col-md-4">
<div class="content-section">
<h3>Our Sidebar</h3>
<p class='text-muted'>You can put any information here you'd like.
<ul class="list-group">
<li class="list-group-item list-group-item-light">Latest Posts</li>
<li class="list-group-item list-group-item-light">Announcements</li>
<li class="list-group-item list-group-item-light">Calendars</li>
<li class="list-group-item list-group-item-light">etc</li>
</ul>
</p>
</div>
</div>
</div>
</main>
But about page I want the above code of block like
<main role="main" class="container">
<div>
{% if messages %}
{% for message in messages %}
<div class="alert alert-{{ message.tags }}">
{{ message }}
</div>
{% endfor %}
{% endif %}
{% block content %}{% endblock %}
</div>
</main>
So is there a way the second block of code is only executed when the page is "about.html"
else the first block should be executed.
I can do these changes if I do not inherit about from base.html, but then I will be repeating a lot of lines of code. That is why I am looking for another approach
EDIT
wondering if something like "{% if url == 'blog-about' %}" exists
If you don't want the sidebar to not appear, you can create another html file called sidebar.html and insert the sidebar code, and another html file called message.html and insert the message template.
Then include this tag in all of your pages {% include sidebar.html %} and {% include message.html %} and leave it for your about.html.
Why is it giving me this strange error: Did you forget to register or load this tag? it was working fine but when i did some changes in this code it started this error... i was going through question related to this issue but could not find the solution....
<div class="container">
<div class="row">
<div class="pagination">
{% for item in post.object_list %}
<!-- {% for item in post %}-->
<div class="card my-3 text-white bg-dark mb-3" style="width: 18rem;">
<img src="/media/{{item.thumbnail}}" class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">{{item.title}}</h5>
<p class="card-text">{{item.intro}}</p>
<!-- href={% url 'bicep' %}-->
read more...
<!-- read more...-->
</div>
</div>
{% if forloop.counter|divisibleby:4 %}
</div>
{% endif %}
{% endfor %}
Django disregards HTML comments. That means django will run this code:
<!-- {% for item in post %}-->
This is what's causing the error because django is expecting an endfor closing tag for this loop.
Either remove this line from your code or use django's comment template tag to comment out the template related code:
{% comment %}
{% for item in post %}
{% endcomment %}
I have a Class-Based ListView as shown below:
class JobByStateView(ListView):
model = State
template_name = 'jobs/jobs_by_state.html'
context_object_name = 'state_list'
ordering = ['name']
paginate_by = 15
I have added the path to urls.py file as shown below:
path('jobs/', JobByStateView.as_view(), name='job-by-state'),
And this how my template looks:
<div class="row">
<div class="col-md-4">
<ul class="list-unstyled mb-0">
{% for state in state_list %}
{% if forloop.counter|divisibleby:"5" == False %}
<li>
{{state.name}}
</li>
{% else %}
<li>
{{state.name}}
</li>
</ul>
</div>
<div class="col-md-4">
<ul class="list-unstyled mb-0">
{% endif %}
{% endfor %}
</ul>
</div>
</div>
When I try to access this templates via the url (http://localhost:8000/jobs) it works as expected and displays the data on the screen. But when I try embed this template within another template as shown below, nothing gets displayed on the web page.
{% include 'jobs/jobs_by_state.html' %}
I would like to display this template as a widget within another template.
Really appreciate, if anyone could please help me in fixing this issue.
Thank you so much in advance for your time and help!
=========================================================================
The other page template is:
{% extends 'base.html' %}
{% block page_content %}
{% include 'carousel.html' %}
{% for job in job_list %}
<div class="listing-wrapper">
<div class="listing-container border-top border-bottom">
<a href="{{ job.get_absolute_url }}">
<h2 class="heading mt-3 mb-1 mx-2 d-inline-block">{{ job.title}}</h2>
</a>
</div>
</div>
{% endfor %}
{% if is_paginated %}
<ul class="pagination justify-content-center my-4">
{% if page_obj.has_previous %}
<li class="page-item">
<a class="page-link bg-dark text-white" href="?page{{page_obj.previous_page_number}}">← Previous Page</a>
</li>
{% endif %}
{% if page_obj.has_next %}
<li class="page-item">
<a class="page-link bg-dark text-white" href="?page{{page_obj.next_page_number}}">Next Page →</a>
</li>
{% endif %}
</ul>
{% endif %}
{% include 'jobs/jobs_by_state.html' with state_list=state_list %}
{% endblock page_content %}
{% block page_sidebar %}
{% include 'simple_search_widget.html' %}
<!-- Social Sharing Buttons -->
<div class="sharethis-inline-share-buttons mt-4"></div>
<!-- Newsletter Widget -->
{% include 'newsletter_widget.html' %}
{% endblock page_sidebar %}
The view for the parent template is as shown below:
class JobList(ListView):
model = Job
template_name = "jobs/job_listings.html"
context_object_name = "job_list"
ordering = ['-published_date']
paginate_by = 10
The following solution from #Charnel and #ChidG worked.
#Shahzan, ok, well you are referring to that variable in your template like this: {% include 'jobs/jobs_by_state.html' with state_list=state_list %}. So if the variable isn't in the context, it can't be passed to the included template, and so the included template won't display anything.
I am beginner of Django and Template language...
Here is my code:
base.html
{% block news%}
<div class="row">
<div class="span6">
<div class="news-content clearfix">
<div class="news-title">Манай хамт олны тухай</div>
<div class="text clearfix>
<img src="{{STATIC_URL}}img/image1.jpg">
# here is some text
</div>
<div class="pull-right">00
<a class="btn btn-small" href="#">Дэлгэрэнгүй</a>
</div>
</div>
</div>
<div class="span6">
<div class="news-content clearfix">
<div class="news-title">#title</div>
<div class="text clearfix">
<img src="{{STATIC_URL}}img/image2.jpg">
# text-2
</div>
<div class="pull-right">
<a class="btn btn-small" href="#">Дэлгэрэнгүй</a>
{% endblock %}
news_list.html
{% extends "base.hmtl"%}
{% block news %}
{% for news in news_list %}
######## here i want to display last 2 news at row #########
{% endfor %}
{% endblock %}
You are getting it all wrong.
The base.html must contain all the code that is to be reused over your website.For example the files like CSS and javascript are included in the base.html
Inside the base.html you are to include a block that is to hold the code that varies from page to page.You can use multiple blocks as well,like header,body, and footer.
When a template is rendered,the requested template "imports" the base.html using {% extends "base.html" %}.After the import,the block defined in the base.html is replace by the block in the requested template.
As per your question,the code you have written in the base.html that defines how to display your news is to come under the news_list.html,under the for loop.
I assume that the news_list is a QuerySet ie a result of a database query and contains the attributes title,content etc
{% extends "base.html" %}
{% block news %}
{% for news in news_list %}
<div class="row">
<div class="span6">
<div class="news-content clearfix">
<div class="news-title">{{ news.title }}</div>
<div class="text clearfix>
<img src="{{STATIC_URL}}img/image1.jpg">
</div>
<div class="pull-right">00
<a class="btn btn-small" href="#">{{ whatever }}</a>
</div>
</div>
</div>
{% endfor %}
{% endblock %}
And your base.html
<html>
CSS,JS here if any
<body>
{% block news %}
{% endblock %}
</body>
</html>
What is the Django way of creating a reusable template?
Example: Suppose a lot of my pages contain a "Latest News" box and following the DRY principle, I would like to define it once and reuse it in the other pages. How would I do this with Django (or Jinja2) templates?
Reading through Django's Template Documentation I get the impression that Django templates offer "top-down" inheritance where the sub-template itself determines in which super-template it is going to be embedded:
<!-- Super-template (not valid, for illustration): -->
<html>
<head><title>Title</title></head>
<body>{% block content %}{% endblock %}</body>
</html>
<!-- Sub-template: -->
{% extends "base.html" %}
{% block content %}
<div class="latest-news">News</div>
{% endblock %}
So what is the technique to reuse a block (a sub-template) in several places?
The most flexible way to reuse template fragments is to define an inclusion_tag. You can pass arguments to your custom tag, process them a bit in Python, then bounce back to a template. Direct inclusion only works for fragments that don't depend on the surrounding context.
Quick example from the docs:
In app/templatetags/poll_extras.py register the tag with a decoration:
from django import template
register = template.Library()
#register.inclusion_tag('results.html')
def show_results(poll):
choices = poll.choice_set.all()
return {'choices': choices}
In app/templates/results.html:
<ul>
{% for choice in choices %}
<li> {{ choice }} </li>
{% endfor %}
</ul>
Calling the tag:
{% load poll_extras %}
{% show_results poll %}
What you're looking for, is {% include "template.html"%} from Django docs.
If you need to use {% block %} you can only do that via the {% extend %} approach. Otherwise, you can use {% include 'some.html' %} to include a bit of HTML in multiple places.
The unofficial Django Reusable App Conventions recommends using these block names:
{% block title %}
{% block extra_head %}
{% block body %}
{% block menu %}
{% block content %}
{% block content_title %}
{% block header %} {% block footer %}
{% block body_id %} {% block body_class %}
{% block [section]_menu %} {% block page_menu %}
If everyone stuck to these conventions, it should make this problem easier. Follow the link to see the description of each block.
Example of using {% include %} tag
All data comes from Django back-end
Many values are passed to card_template.html using include tag in page1.html
card_template.html
<style>
.choices_div {
border-radius: 5rem;
}
.card-footer {
background-color: transparent;
border: transparent;
}
</style>
<div class="col mb-5 px-4">
<div class="card h-100 w-100 jumbotron choices_div {{ bg_color|default:'' }}">
<div class="card-body p-0">
<h3 class="card-title text-center">{{ card_title|capfirst }}</h3>
<ul class="card-text mt-3">
{% for c in card_body_list %}
<li>{{ c }}</li>
{% endfor %}
</ul>
</div>
<div class="card-footer text-center pt-4">
{% if get_post_request == 1 %}
<a class="btn btn-light" href="{{ href }}">{{ button_text }}</a>
{% else %}
<form method="post">
{% csrf_token %}
<button type="submit" class="btn btn-light w-75" name="category"
value="{{ button_value }}">{{ button_text }}</button>
</form>
{% endif %}
</div>
</div>
</div>
page1.html
{% extends 'core/core.html' %}
{% block body %}
<div class="jumbotron bg-white">
<div class="container">
<div class="mb-5 text-center">
<h1>Choose user category</h1>
<h5>Once choosen, the user category cannot be changed</h5>
</div>
<div class="row row-cols-lg-2 justify-content-around">
{% for object in object_list %}
{% cycle 'bg_peacock' 'bg_sunset' 'bg_skin' 'bg_brown' as bg_color silent %}
{% include 'core/card_template.html' with card_title=object.category card_body_list=object.description get_post_request=2 button_text='Select' bg_color=bg_color button_value=object.id %}
{% endfor %}
</div>
</div>
</div>
{% endblock %}
As other answers have mentioned, the simplest approach is direct inclusion:
{% include 'mytemplate.html' %}
It is possible to modify the context of the rendered template (Or in simpler terms, to pass variables to the template) using
{% include 'mytemplate.html' with poll=poll %}
To use the traditional polls example, the template I would write would be:
<div class="stylish-poll">
{% for choice in poll.choices %} <!-- poll is a template variable -->
{% include 'choice_template.html' with choice=choice %}
{% endfor %}
</div>
Another potentially useful thing to know is that the only keyword prevents the template variable poll being passed into 'choice_template.html' which it would be by default. If you do not want the choice template to have access to {{ poll }} then the include statement looks like:
{% include 'choice_template.html' with choice=choice only %}
Documentation: https://docs.djangoproject.com/en/dev/ref/templates/builtins/#include
Aïe, my fault – the answer is given in the Django Reference (and not discussed in the aforementioned Django Template Documentation)…
So: Just use {% include sub_template_name %}.
even though the question is asked years ago, any way I will show you the method that worked for me.
base.html
In your base template you need to define all of your blocks that you need to reuse in your other templates,
<html>
<head>
<meta name="description" content="{%block description%}{%endblock%}">
<meta name="keywords" content="{%block keywords%}{%endblock%}">
<title>{%block title%}{%endblock%}</title>
</head>
<body>
<!---other body stuff--->
{%block content%}
{%endblock%}
</body>
</html>
home.html
{%extends 'base.html'%}
<!--you can reuse all blocks here-->
{%block description%}Django reusable blocks, for every bage{%endblock%}
{%block keywords%}django,block, resuable,meta,title,{%endblock%}
{%block title%}django reuseable blocks for title, meta description and meta keywords{%endblock%}
{%block content%}
<div>
<h1> reuse blocks</h1>
</div>
{%endblock%}