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 %}
Related
{% 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.
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
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
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.
So, I have a number of objects I wish to render in a loop. I.E. Render each of the 5 latest posts on the home page. Each of these posts will be displayed differently whether or not the user is logged in.
I have a question: How would I go about making this distinction? I imagine having a template like this
{% if user.is_logged_in %}
{% for post in latest_posts %}
post.render_long_form
{% endfor %}
{% else %}
{% for post in latest_posts %}
post.render_short_form
{% endfor %}
{% endif %}
How can I make the functions render_short_form and render_long_form return the appropriate HTML snippits? I would like them to call other templates for rendering under the hood.
Thanks!
Why don't not use {% include %} tag?
{% if user.is_logged_in %}
{% for post in latest_posts %}
{% include 'long_form.html' %}
{% endfor %}
{% else %}
{% for post in latest_posts %}
{% include 'short_form.html' %}
{% endfor %}
{% endif %}
Or, more DRY version:
{% for post in latest_posts %}
{% if user.is_logged_in %}
{% include 'long_form.html' %}
{% else %}
{% include 'short_form.html' %}
{% endif %}
{% endfor %}