This question already has answers here:
How to repeat a "block" in a django template
(15 answers)
Closed 6 years ago.
<html>
<head>
<title>{% block title %}{% endblock %}</title>
</head>
<body>
<h1>{% block title %}{% endblock %}</h1>
</body>
</html>
This is my template, more or less. The h1 heading is always the same as the title tag. The above snippet of code is not valid because there can't be two blocks with the same name. How do I handle this without repeating myself?
edit to clarify: I have a ton of child templates which are inherited from this one template, and so making a new {{title}} variable for each template is not a very good solution. Previously I had it set up like this:
base.html:
<title>{% block title %}{% endblock %}</title>
then in base_view.html (extending base.html):
<h1>{% block title %}{% endblock %}</h1>
then in base_object.html (extending base_view.html):
{% block title %}my title goes here{% endblock %}
and it just worked somehow. I refactored my templates so theres just base.html, and base_object.html How can I get this functionality back?
In base.html:
<head>
<title>{% block title %}{% endblock %}</title>
</head>
<body>
<h1>{% block h1 %}{% endblock %}</h1>
</body>
Then, make another "base" layer on top of that called content_base.html (or something):
{% extends "base.html" %}
{% block h1 %}{% block title %}{% endblock %}{% endblock %}
Now have all your other templates extend content_base.html. Whatever you put in block "title" in all your templates will go into both "title" and "h1" blocks in base.html.
{% extends "base.html" %}
{% with "Entry Title" as title %}
{% block title %}{{ title }}{% endblock %}
{% block h1 %}{{ title }}{% endblock %}
{% endwith %}
That could work if you're really worried about keeping title out of the views and not repeating yourself.
It looks like your layout is solid. You have a base.html template that defines the basic structure and outer layout for each page in your app. You also have base_object.html that extends this template.
You'd like each page to have a unique title and a matching h1 (I think). This best way to do this is to define two separate blocks in your base.html template.
<html>
<head>
<title>{% block title %}Default Title{% endblock %}</title>
</head>
<body>
<h1>{% block h1 %}{% endblock %}</h1>
</body>
</html>
In your child templates, you need to override both of these if you'd like them to be identical. I know you feel this is counter-intuitive, but it is necessary due to the way template inheritance is handled in Django.
Source: The Django template language
Finally, note that you can't define multiple {% block %} tags with the same name in the same template. This limitation exists because a block tag works in "both" directions. That is, a block tag doesn't just provide a hole to fill -- it also defines the content that fills the hole in the parent. If there were two similarly-named {% block %} tags in a template, that template's parent wouldn't know which one of the blocks' content to use.
The children look like this:
{% extends "base.html" %}
{% block title %}Title{% endblock %}
{% block h1 %}Title{% endblock %}
If this bothers you, you should set the title from the view for each object as a template variable.
{% block title %}{{ title }}{% endblock %}
{% block h1 %}{{ title }}{% endblock %}
Django strives to keep as much logic out of the template layer as possible. Often a title is determined dynamically from the database, so the view layer is the perfect place to retrieve and set this information. You can still leave the title blank if you'd like to defer to the default title (perhaps set in base.html, or you can grab the name of the site from the django.contrib.sites package)
Also {{ block.super }} may come in handy. This will allow you to combine the contents of the parent block with additional contents from the child. So you could define a title like "Stackoverflow.com" in the base, and set
{% block title %}{{ block.super }} - Ask a Question{% endblock %}
in the child to get a title like "Stackoverflow.com - Ask a Question"
Pass a variable to your template, maybe called title. Then replace your title block with {{ title }}. To pass this into your template in your view make sure you have:
def myview(request):
t = loader.get_template("mypage.html")
title = "My Title"
c = Context({"title" : title })
HttpResponse(t.render(c))
Then in your template you will have:
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
<h1>{{ title }}}</h1>
</body>
See also: How to repeat a "block" in a django template
Related
I have the following structure of templates:
main.html
<html>
<body>
<p>
This works: {% block title %}{% endblock %}
</p>
{% include 'heading.html' with title=title %} {# but this does not work since it is not a variable #}
</body>
</html>
heading.html
<p>
{{ title }}
</p>
page.html
{% extends 'main.html' %}
{% block title %}test title{% endblock %}
How can I pass the title from page.html to heading.html? Ideally, it should be defined as a block like now, but alternatives are also welcome. I'd like to contain the solution within the templates if possible.
Clarification:
This is a minimal example, but I have multiple pages like main.html that share a larger header that has title and some other variables that I'd like defined in the child template (not necessarily as variable as long as the text is passed).
I could put the title into the view code, but this solution would just decrease the separation of displayed data from the logic.
Use a block around the include with variables, and then wrap {{ block.super }} in the with template tag.
main.html:
<html>
<body>
<p>
This works: {% block title %}{% endblock %}
</p>
{% block with_variables %}
{% include 'heading.html' %}
{% endblock %}
</body>
</html>
page.html:
{% extends 'main.html' %}
{% block title %}test title{% endblock %}
{% block with_variables %}
{% with title="variable title" %}
{{ block.super }}
{% endwith %}
{% endblock %}
You may name it {% block heading %}, or nest the whole main.html in {% block content %}.
instead of {% include %}, you might want to use custom template tags with returning html or extension like slippers
You don't need heading.html. You can use the context variable title directly; as long as you pass it to your render function in your view, e.g.:
views.py
def my_view(request):
context = {'title': 'Hello World!'}
return render(request, 'page.html', context=context)
main.html
<html>
<body>
<p>
This is my title:
{% block title %}{% endblock %}
</p>
</body>
</html>
page.html
{% extends 'main.html' %}
{% block title %}
<strong>{{title}}</strong>
{% endblock %}
If you have administrative rights to your Django installation, an easy and elegant solution would be to switch your Django's template renderer to Jinja2 instead using django-jinja as a backend.
The main advantage of Jinja2 for the needs of this question is that it supports assignment of a block to a variable through block assignments. Since Jinja2 is inspired by the Django template language, your existing templates will need few modifications, if any.
With Jinja2 as a template renderer, you can set the title variable with a block of HTML content in the child template:
page.html
{% extends 'main.html' %}
{% set title %}test title{% endset %}
The title variable will then work in the shared template:
main.html
<html>
<body>
<p>
Main template works: {{ title }}
</p>
{% include 'heading.html' %}
</body>
</html>
And it will also work in the included template:
heading.html
<p>
Included template also works: {{ title }}
</p>
Demo: https://replit.com/#blhsing/AlarmedCleverDebugmonitor
One possible solution is to split heading.html into two and add a {% block %} in-between, but this is an ugly workaround that is prone to bugs with unclosed tags.
I am searching for a better alternative.
main.html
...
{% include 'heading1.html' %} {# containing <p> #}
{% block title %}{% endblock %}
{% include 'heading2.html' %} {# containing </p> #}
...
Additionally, if white spaces are important, there has to be no new line between includes and the block.
add your title to the rendering context and it will be visible in page, main and included heading.
I am trying to use jinja for setting default title for page for that I am using
Home{% block title %}
{% endblock title %}</title>
now on some other page I need to use this block so there if I am using only -About is shown on the title
{% block title %}
-About
{% endblock title %}</title>
expected is Home-About
if I use blockextend whole home page is coming on about page which I don't way how can I correct
this
{% extends 'base.html' %}
{% block title %}
About
{% endblock title %}</title>
The way I would do the title is have something like this in your base.html file
{% if title %}
<title>Home - {{title}}</title>
{%else%}
<title>Home</title>
{%endif%}
And then for each of your routes when you render the template you can set a title, if no title is set then the title will just be Home.
For example
retrun render_template("about.html", title = "About")
Would give you the title "Home - About"
If you want to use your method of doing it, I think what you have done should work, but in the base.html file you can change {% endblock title %} to just
{%endblock%}, and do the same in the other html file. Maybe that will solve your issue?
I hope that helps, sorry if I have misunderstood what you wanted.
To achieve this, it is better to use jinja macros. here is how:
my_macros.html
{% macro render_title(arg1, arg2) %}
# write your jinja html here
{% endmacro%}
{% macro render_something(arg1, arg2) %}
# write your jinja html here
{% endmacro%}
Then in your html where you want to use the macro:
{% extends 'base.html' %}
{% from 'my_macros.html' import render_title %}
{% block content %}
{{ render_title("something", "something else") }}
# jinja html anywhere
{% endblock content %}
This seems so simple and yet it refuses to work...
I have my base.html file:
{% load static %}
<html>
<head>
<meta charset="utf-8">
<title>
{% block title %}
Simple Skeleton
{% endblock title %}
</title>
and my home.html file:
{% extends "base.html" %}
<% block title %>
Resource List
<% endblock %>
(they are both a bit longer but I feel this is all that is necessary)
The home.html completely fails to overwrite the sections within the code blocks - the page title remains "Simple Skeleton" and not "Resource List" despite me accessing the home.html file.
What am I doing wrong?
Django template tags are written between {% … %}, not <% … %>, so {% block title %}, not <% block title %>:
{% extends "base.html" %}
{% block title %}
Resource List
{% endblock %}
By not using the proper template tag, Django will not render this content: it is content outside a block, so it will not have an effect on the inherited template.
You have a typo error in home.html. Use {% %} for template tags instead of <% %>.
{% extends "base.html" %}
{% block title %}
Resource List
{% endblock %}
This question already has answers here:
Render Externally Defined Block In Django Template
(3 answers)
Closed 8 years ago.
I have 3 pages, and all of them have the same menu on the top of each html file.
There are many a tags in the menu, and I have problem when I'd like to revised all link in a tag.
I'd like to write the menu in other file called menu.txt, and use template to load the menu.txt and then combine menu with other parts of the page.
Is there any efficiency way to do it?
Except load the page in view.py and pass value to template.
Thank you.
Use include in your template file. See the docs.
Example
{% extends 'base.html' %}
{% block content %}
{% include 'includes/menu.html' %}
<h1>Hello World</h1>
<!-- ... -->
{% endblock content %}
Template inheritance
The most powerful – and thus the most complex – part of Django’s template engine is template inheritance. Template inheritance allows you to build a base “skeleton” template that contains all the common elements of your site and defines blocks that child templates can override.
It’s easiest to understand template inheritance by starting with an example:
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="style.css" />
<title>{% block title %}My amazing site{% endblock %}</title>
</head>
<body>
<div id="sidebar">
{% block sidebar %}
<ul>
<li>Home</li>
<li>Blog</li>
</ul>
{% endblock %}
</div>
<div id="content">
{% block content %}{% endblock %}
</div>
</body>
</html>
This template, which we’ll call base.html, defines a simple HTML skeleton document that you might use for a simple two-column page. It’s the job of “child” templates to fill the empty blocks with content.
In this example, the block tag defines three blocks that child templates can fill in. All the block tag does is to tell the template engine that a child template may override those portions of the template.
A child template might look like this:
{% extends "base.html" %}
{% block title %}My amazing blog{% endblock %}
{% block content %}
{% for entry in blog_entries %}
<h2>{{ entry.title }}</h2>
<p>{{ entry.body }}</p>
{% endfor %}
{% endblock %}
The extends tag is the key here. It tells the template engine that this template “extends” another template. When the template system evaluates this template, first it locates the parent – in this case, “base.html”.
you can refer for extending commom part on each html page
http://www.webforefront.com/django/createreusabledjangotemplates.html
I'm trying to pass some variables from the child page to the template. This is my python code:
if self.request.url.find("&try") == 1:
isTrying = False
else:
isTrying = True
page_values = {
"trying": isTrying
}
page = jinja_environment.get_template("p/index.html")
self.response.out.write(page.render(page_values))
The template:
<html>
<head>
<link type="text/css" rel="stylesheet" href="/css/template.css"></link>
<title>{{ title }} | SST QA</title>
<script src="/js/jquery.min.js"></script>
{% block head %}{% endblock head %}
</head>
<body>
{% if not trying %}
<script type="text/javascript">
// Redirects user to maintainence page
window.location.href = "construct"
</script>
{% endif %}
{% block content %}{% endblock content %}
</body>
</html>
and the child:
{% extends "/templates/template.html" %}
{% set title = "Welcome" %}
{% block head %}
{% endblock head %}
{% block content %}
{% endblock content %}
The problem is, I want to pass the variable "trying" into the parent, is there a way to do this?
Thanks in advance!
The example on the Jinja2 Tips and Tricks page explains this perfectly, http://jinja.pocoo.org/docs/templates/#base-template. Essentially, if you have a base template
**base.html**
<html>
<head>
<title> MegaCorp -{% block title %}{% endblock %}</title>
</head>
<body>
<div id="content">{% block content %}{% endblock %}</div>
</body>
</html>
and a child template
**child.html**
{% extends "base.html" %}
{% block title %} Home page {% endblock %}
{% block content %}
... stuff here
{% endblock %}
whatever python function calls render_template("child.html") will return the html page
**Rendered Page**
<html>
<head>
<title> MegaCorp - Home page </title>
</head>
<body>
<div id="content">
stuff here...
</div>
</body>
</html>
I think that you are looking to highlight active menus in the base layout and you need something like this
{% extends 'base.html' %}
{% set active = "clients" %}
then use can use "active" inside base.html
You just need to declare that variable before extending the template, so the extended template will have access to to the variable trying
{% set trying = True %} <----------- declare variable
{% extends "/templates/template.html" %}
{% set title = "Welcome" %}
{% block head %}
{% endblock head %}
{% block content %}
{% endblock content %}
Few years later but hoping it may help latecomers
I do not understand your problem. When you pass variables to the context (as you do with trying) these variables will be available in the child and the parent.
To pass title to the parent, you have to use inheritance, sometimes in combination with super : http://jinja.pocoo.org/docs/templates/#super-blocks
See also this question: Overriding app engine template block inside an if