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 %}
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'm trying to set up a site in Flask (formerly familiar with django) and I'm having difficulties getting templates to render properly.
I have a base.html, home.html and a navigation.html. My route renders home.html template, which extends the base.html template, and that works fine. But within my base.html, there is another block called navigation. Nothing I enter into my navigation file seems to render at all.
base.html
<DOCTYPE html>
<html>
<head>
<title>{% block title %} {% endblock %} </title>
</head>
<body>
{% block navigation %}
{% endblock %}
{% block content %}
{% endblock %}
</body>
</html>
home.html
{% extends 'base.html %}
{% block title %} lorem ipsum {% endblock %}
{% block content %}
<h1> Here is text </h1>
<p> Lorem ipsum paragraph </p>
{% endblock %}
navigation.html
{% extends 'base.html %}
{% block navigation %}
<nav>
insert any html here, I used a p tag
</nav>
{% endblock %}
I can't get anything within navigation.html to display, no matter what it is.
In django, I don't remember having this issue.
To my best of critical thinking, I would assume that I'm rendering home.html and not base.html so therefore home.html can use base, but it can't extend it's reach to actually use navigation.html.
I'm not sure, and I'm tired of racking my head into my desk.
Making a assumption here, so please clarify if I get this wrong.
I suspect what you mean to do is {% include 'navigation.html' %} from within index.html (and in all other pages that want that common navigation).
If that's the case, you can remove the {% extends ... %} from navigation.html.
I have a base.html file that looks like this:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
{% block header %}{% endblock %}
</head>
<body>
{% block content %}{% endblock %}
{% block footer %}{% endblock %}
</body>
</html>
and I have a file, auth.html that extends this:
{% extends "base.html" %}
{% block content %}
[MY CONTENT]
{% endblock %}
which works fine, but I also want to have a separate header.html file that plugs into the header block above.
What's the correct way to structure auth.html and header.html in order to include both and to have both extend base.html?
I tried adding a {% include header.html %} line to auth.html, and structuring header.html as follows:
{% extends "base.html" %}
{% block header %}
[HEADER CONTENT HERE]
{% endblock %}
but that didn't work. How should I be doing this?
You need {{ block.super }}:
If you need to get the content of the block from the parent template,
the {{ block.super }} variable will do the trick. This is useful if
you want to add to the contents of a parent block instead of
completely overriding it.
Its burried in the template inheritance documentation.
Suppose you want to add extra stuff to the header block in auth.html. header is defined in index.html:
Your auth.html would look like:
{% extends "index.html" %}
{% block header %}
{{ block.super }}
Your extra stuff, which will come after whatever was in the header block
{% endblock %}
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
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