Inherit template blocks from parent of parent in Django - python

I've 3 template files named **base.html**, **navbar.html** and **dashboard.html**.
base.html is the main parent file which has a **{% block content %}**.
Navbar has **{% block navtitle %}**.
Now What I want to do is, I want **navtitle** block in my 'dashboard.html' file.
Both navbar.html and dashboard.html extends **base.html**. I'm able to get **content** block from base.html file, but can't get navbar block.
Please guide me how can I do the same
Sample files below
base.html
{% block content %} {% endblock %}
navbar.html
{% extends 'base.html' %}
{% block navtitle %} {% endblock %}
dashboard.html
{% extends 'base.html' %}
{% block content %} Demo {% endblock %} # Able to print it
{% block navtitle %} Demo 2 {% endblock %} # Not able to print it
I also tried to extend navbar.html file in dashboard.html file but still no luck.

Using Inheritance (1/2)
base.html
{% block content %} {% endblock %}
{% block navtitle %} {% endblock %}
dashboard.html
{% extends 'base.html' %}
{% block content %} Demo {% endblock %}
{% block navtitle %} Demo 2 {% endblock %}
Using Inheritance (2/2)
useful when some templates will only inherit from base.html while others will inherit from navbar.html
base.html
{% block content %} {% endblock %}
{% block navtitle %} {% endblock %}
navbar.html
{% extends 'base.html' %}
{% block navtitle %} {% endblock %}
dashboard.html
{% extends 'navbar.html' %}
{% block content %} Demo {% endblock %}
{% block navtitle %} Demo 2 {% endblock %}
Using include
base.html
{% block content %} {% endblock %}
{% include "path/to/navbar.html" %}
navbar.html
<div>Some html</div>
dashboard.html
{% extends 'base.html' %}
{% block content %} Demo {% endblock %}
{% block navtitle %} Demo 2 {% endblock %}
Checkout django's templates documentation for include and inheritance

Related

{% block content %}{% endblock %} doesn't load/work

{% extend 'base.html' %}
{% block content %}
<h2>NEW SEARCH</h2>
{% endblock %}
The template above doesn't work as it should.
You should use:
{% extends '<app_name>/base.html' %}
You forgot the s character when extending the template file.

Global variables not defined in {% set %}

I have the following:
layout.html
{% if enableEntry or enableExit %}
{% from "cp.layout.html" import entry, exit %}
{% endif %}
<!DOCTYPE html>
<html lang="en">
<body>
{% if enableEntry %}{{ entry }}{% endif %}
{% if enableExit %}{{ exit }}{% endif %}
{% block body %}{% endblock %}
</body>
</html>
cp.layout.html
{% set entry %}
...
{% if offer.text_id == "mcd" %}
Mcdonald
{% elif offer.text_id == "bk" %}
Burger King
{% endif %}
...
{% endset %}
in my view:
def test():
.... (offer is defined here) ...
return render_template('layout.html', offer=offer)
I am getting an error that UndefinedError: 'offer' is undefined
Is there a way to pass variables that have global scope in the view to {% set %} blocs?
Seems like you never include your test.html under layout.html
I not sure is this help, this is my jinja 2 template design u can try
layout.html
{%- extends "test.html" %}
{# {% include "test.html" %} #}
{% block content %}
{{ super() }}
{%- endblock %}
test.html
{% block content %}
<div>
<h1>{{ offer }}</h1>
</div>
{% endblock %}
Let me know is this method work will give more explanation later

Jinja2 templates inheritance

With Jinja2, do all blocks need to be defined in the base template from which all other templates extend? For instance, given the following templates:
<-- ultra_base.j2 -->
<head>
</head>
<body>
{% block content %}{% endblock %}
{% block extra_js %} {% endblock %}
</body>
and
<-- child.j2 -->
{% extends ultra_base %}
{% block extra_js %}
<script src="somefile.js">
{% endblock %}
{% block page_js %} {% endblock %}
and
<-- grandchild.j2 -->
{% extends child %}
{% block content %}
<h2> Grandchild Content </h2>
{% endblock content %}
{% block page_js %}
<script src="grandchild.js"></script>
{% endblock page_js %}
The page_js block is never rendered. Is there some way to render it without changing ultra_base?
You could render page_js by putting the {% block page_js %} {% endblock %} inside the extra_js block in child.j2:
<-- child.j2 -->
{% extends ultra_base %}
{% block extra_js %}
<script src="somefile.js">
{% block page_js %}
{% endblock %}
{% endblock %}
The problem is that the page_js block in child.j2 is "in the middle of nowhere", it does not alter any block of the ulta_base.j2, so Jinja2 will not render anything from it. The solution is quite simple, you don't even need to define a new extra_js block, just use Jinja2's super() function:
ultra_base.j2 remains the same:
<!-- ultra_base.j2 -->
<head>
</head>
<body>
{% block content %}{% endblock %}
{% block extra_js %} {% endblock %}
</body>
the child.j2 template:
<!-- child.j2 -->
{% extends ultra_base %}
{% block extra_js %}
{{ super() }}
<script src="somefile.js"></script>
{% endblock %}
and the grandchildj2:
<!-- grandchild.j2 -->
{% extends child %}
{% block content %}
<h2> Grandchild Content </h2>
{% endblock content %}
{% block extra_js %}
{{ super() }}
<script src="grandchild.js"></script>
{% endblock extra_js %}
Jinja2 will take care of including block contents from the parent templates.

How to fetch the entire table data and show them in the user interface in django using templates

I have defined a model called "Files" having fields as Id(auto genrated) and file_name.I want to fetch all the file names from the database and show them as a list on the UI.I am developing a django project.
I have added a read_files.html in the templates folder.
{% extends "home/base.html" %}
{% block title %}title{% endblock %}
{% block subtitle %}Read File{% endblock %}
<body>
<ul>
{% for f in Files %}
<li>{{ f.name }}</li>
{% empty %}
<li>Sorry, no files present in this list.</li>
{% endfor %}
</ul>
</body>
{% endblock %}'
But i am not able to see the correct results. Either it gives error
'Invalid block tag: 'endblock'' or 'incorrectly spelled text string endfor'
It seems you are missing a block opening tag after the subtitle block:
I added a {% block content %} tag (change "content" for the right block name
{% extends "home/base.html" %}
{% block title %}title{% endblock %}
{% block subtitle %}Read File{% endblock %}
{% block content %}
<body>
<ul>
{% for f in Files %}
<li>{{ f.name }}</li>
{% empty %}
<li>Sorry, no files present in this list.</li>
{% endfor %}
</ul>
</body>
{% endblock %}
also don't add extra characters after you finish a block if you are extending a template

Override a block from an include via extend is blank?

So I have a base template, which includes a header:
base.html:
{% include "header.html" %}
header.html:
<ul>
<li><a>Link</a></li>
<li><a>Link</a></li>
<li><a>Link</a></li>
</ul>
{% block diskspace %}Test{% endblock %}
Then I would like to override the diskspace block from a template which extends the base, for instance:
album.html:
{% extends "base.html" %}
{% block diskspace %}
<p>You need more space!</p>
{% endblock %}
Unfortunately however diskspace only contains "Test" and is not overridden.
Is what I'm attempting possible, or do I need to go another route?
SOLUTION
Based on sergzach's answer below, here's what I ultimately implemented:
header.html:
<ul>
<li><a>Link</a></li>
<li><a>Link</a></li>
<li><a>Link</a></li>
</ul>
{% if show_diskspace %}
<p>You need more space!</p>
{% endif %}
base.html
{% block header %}
{% include "header.html" %}
{% endblock %}
album.html
{% extends "base.html" %}
{% block header %}
{% include "header.html" with show_diskspace="True" %}
{% endblock %}
header.html:
<ul>
<li><a>Link</a></li>
<li><a>Link</a></li>
<li><a>Link</a></li>
</ul>
{{diskspace}}
base.html
{% block header %}
{% include "header.html" with diskspace='Test'%}
{% endblock %}
album.html
{% extends "base.html" %}
{% block header %}
{% include "header.html" with diskspace='<p>You need more space!</p>'|safe %}
{% endblock %}

Categories