How to chain {% includes %} in django templating - python

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 %}

Related

Can't get Django Template Inheritance to work

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 %}

Django, how to use render_to_response with many templates

Hello i am newbie in Django, started to learn it today and i have problem with template inheritance
i have such function in my view:
def show(request, id=1):
return render_to_response('template1.html', {
'name': name,
'model1': Model1.objects.get(id=id),
'model2': Model2.objects.get(id=id).model1,
})
And i have 3 different templates, main.html with such code:
<body>
{% block block1 %}
{% endblock %}
{% block block2 %}
{% endblock %}
</body>
</html>
and two more tempaltes that contains code like that:
{% extends 'main.html' %}
{% block block1 %}
<h2>{{ var }}</h2>
<pre>{{ var }}</pre>
{% endblock %}
second one is very similar so i wont show it, problem is: i dont know which one to put in render_to_response function.
if i put main.html:
return render_to_response('main.html', {
it doesn't load any templates, but content from main.html appears well, i can just see empty space on page
if i put template1:
return render_to_response('template1.html', {
It load only content from main and from template1.html but i need content from template2.html
if i put template2.html to function it only shows content from main.html and from template2.html but no content from template1.html
Please help me how to solve that problem.
Option 1) Try using the {% include %} tag.
main.html
<head> ... </head>
<body>
{% block content %}
{% endblock content %}
template1.html
{% extends "main.html" %}
{% block content %}
<h1>Hello world</h1>
{% include "nested_template2.html" %}
{% endblock content %}
nested_template2.html
<p>The world is smaller than you think.</p>
In your view/controller:
return render_to_response('template1.html', {
Option 2) Chain {% extends ... %} tags as deep as you want. I frquently use this structure:
templates/
----base.html
----projects/
----_.html
----detail.html
----list.html
The base.html is the master layout. The folder/_.html is specific to a "stage" (more modular content).
base.html
<head> ... </head>
<body>
{% block stage_content %}
{% endblock stage_content %}
projects/_.html
{% extends "main.html" %}
{% block stage_content %}
<h1>Project Stage</h1>
{% block page_content %}
{% endblock page_content %}
{% endblock stage_content %}
projects/list.html
{% extends "projects/_.html" %}
{% block page_content %}
{% for project in projects %}
<li>{{ project.name }}</li>
{% endfor %}
{% endblock page_content %}
projects/detail.html
{% extends "projects/_.html" %}
{% block page_content %}
Viewing project {{ project.name }}
{% endblock page_content %}
In your view/controller:
return render_to_response('projects/detail.html', {

is dividing a template into parts and including each part bad?

I have a base template that I'd like to split up into three parts: header, body, footer. Then I use the base template to include the three sub-templates. However, from what I've seen, this means I cannot override {{ block }} content. Is using includes a bad idea then? Or is there a way to override block content in an included template?
I know that you can send static context variables to the included segment, but it needs to be more dynamic.
My code:
In header.html
<html>
<head>
<script url="..."></script>
<link rel="..." />
{% block head_extension %}
{% endblock %}
</head>
<body>
<header>
<div class="headerstuff">
</div>
</header>
Then in the body.html file:
<div class="container">
{% block content %}
Foo fum my content
{% endblock %}
</div>
footer.html:
<footer>
{% block footer %}
Copyright 2015
{% endblock %}
</footer>
</body>
</html>
base.html:
{% include "header.html" %}
{% include "body.html" %}
{% include "footer.html" %}
<!-- and the part that doesn't work -->
{% block head_extension %}
<script src="unique_script"></script>
{% endblock %}
{% block content %}
My unique content
{% endblock %}
{% block footer %}
Copyright 2011
{% endblock %}
<!-- end broken django templating try -->
Am I doing something wrong? The templating documentation seemed to indicate that what I am trying to do doesn't work. It seems like this would be the best way to create easy-to-read templates. Is it better just to have all parts in one large file? As you can imagine, the header, body, and footer elements are much larger than this demonstration. But the point remains.
I am hoping there is a way to do what I'm thinking of that I'm not aware of.
Thanks in advance
Your approach is fine but you are doing this in wrong order. First of all the html starting <html> and ending tag </html> should not be split into different files, it is good to have it in base.html.
Below is an example of how to follow the breakup structure:
base.html
<html>
<head>
<!-- Some stuff here which should be included in all templates for example js or css -->
{% block extra_css %}
<!-- to included app-template dependent css -->
{% endblock extra_css %}
{% block extra_js %}
<!-- to included app-template dependent js -->
{% endblock extra_js %}
{% block extra_head %}
<!-- for anything else inside head -->
{% endblock extra_head %}
</head>
<body>
{% block menu %}
<!-- Default menu here -->
{% block extra_menu %}
<!-- extend menu based on template -->
{% endblock extra_menu %}
{% endblock menu %}
{% block content %}
<div>This is good</div>
{% endblock content %}
{% include "footer.html" %}
{% block bottom_js %}
<!-- if you want to have manual js scripts at bottom -->
{% endblock bottom_js %}
</body>
</html>
Now base.html is all setup now lets suppose from another child template you want to override the base.html block content you will do:
child.html
{% extends "base.html" %}
{% block content %}
<div>This is really good</div>
{% endblock content %}
So when the page will be loaded you will see this is really good instead of this is good (which was defined in base.html inside content block) because you just override it.
If you want that whatever inside the content block in base.html should also be preserved then you need to extend the block rather than overriding it completely by using method {{ block.super }}
child.html
{% extends "base.html" %}
{% block content %}
{{ block.super }}
<div>This is really good</div>
{% endblock content %}
Now you will see both this is good and this is really good. Hope this will clarify your concept and will lead you good.

Wrap jinja2 block content in intermediate template

Is it possible to calla child block from an intermediate parent template?
Example
// base.html
<body>
{% block content %}{% endblock %}
</body>
// base-for-pages.html
{% block content %}
<div class="wrap">
{% block content %}{% endblock %}
</div>
{% endblock %}
// template3.html
{% block content %}
<h1>Actual content</h1>
{% endblock %}
I know it doesn't work like this but is it possible to set up something like in base-for-pages.html so that you can wrap the contents of a child template before it's sent to the parent template?
It seems like overkill to create a new root template just to wrap the contents of a child template.

Django templates: overriding blocks of included children templates through an extended template

I'm wondering if anyone knows how to deal with the following quirky template structure:
### base.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
<title> {% block title %} Title of the page {% endblock %} </title>
</head>
<body>
<header>
{% block header %}
{% include "base/header.html" %}
{% endblock header %}
</header>
{% block content %}{% endblock %}
</body>
</html>
### base/header.html
<div id="menu-bar">
{% block nav %}
{% include "base/nav.html" %}
{% endblock %}
</div>
### base/nav.html
<nav id="menu">
<ul>
<li>
My Profile
</li>
<li>
My Favorites
</li>
{% block extra-content %}{% endblock %}
</ul>
</nav>
And, the heart of the matter:
### app/somepage.html
{% extends "base.html" %}
{% block content %}
<p>Content is overridden!</p>
{% endblock %}
{% block extra-content %}
<p>This will not show up, though...</p>
{% endblock %}
{% block nav %}
<p>Not even this.</p>
{% endblock %}
The problem is when extending a template you can only override the blocks declared in the parent only, not any of its children.
I suppose I could make base.html a husk of empty unused nested blocks covering all future contingencies, but would even that override properly? And is that the only way?
If you're wondering why I have a bi-directional include/extends workflow around base.html, I have many sub-templates that I want to get used all across the project: Headers, footers, navs, sidebars, etc. They all will be consistant in structure across the entire site, but in many cases a whole subdivision of the site will only need a few of those sub-templates. My idea was to define the sub-templates under the templates/base folder, and have templates/base-type1.html, templates/base-type2.html, etc to extend in other places. Each type would only reference the sub-templates needed, and override them to place content as needed.
It seems to be little known that you can use the with keyword with the include to pass variables into the context of an included template - you can use it to specify includes in the included template:
# base.html
<html>
<body>
{% block header %}{% include "header.html" %}{% endblock %}
</body>
</html>
# header.html
# some stuff here
<div id="header">
<img src="logo.png">
{% include nav_tmpl|default:"navigation.html" %}
</div>
# special_page.html (uses other navigation)
{% extends "base.html" %}
{% block header %}
{% include "header.html" with nav_tmpl="special_nav.html" %}
# you might also want to wrap the include in an 'if' tag if you don't want anything
# included here per default
{% endblock %}
This approach saves you at least from having one additional file just for the purpose of overwriting a block. You can also use the with keyword to pass a value through a bigger hierarchy of includes as well.
A terser variant to the solution proposed by #Bernhard Vallant:
# base.html
<html>
<body>
{% block header %}{% include "header.html" %}{% endblock %}
</body>
</html>
# header.html
# some stuff here
<div id="header">
<img src="logo.png">
{% include nav_tmpl|default:"navigation.html" %}
</div>
# special_page.html (uses other navigation)
{% extends "base.html" %}
{% block header %}
{% with nav_tmpl="special_nav.html" %}
{{ block.super }}
{% endwith %}
{% endblock %}
You can solve this by extending your currently-included templates, then including the extension instead of the the currently-included base template.

Categories

Resources