71
Django does not process blocks in included files.
The include tag should be considered as an implementation of “render this subtemplate and include the HTML”, not as “parse this subtemplate and include its contents as if it were part of the parent”. This means that there is no shared state between included templates — each include is a completely independent rendering process. (Django template tag documentation)
12
I came across this problem and ended up with the following compromise, hoping someone else might find it useful. It relies on using with
blocks in the child templates.
base.html wants to reuse a common nav.html include, but define some blocks where variables inside nav.html might be overriden by child templates.
<!-- base.html: -->
<html>
[...]
<nav class="desktop">
{% block desktop_nav %}
{% include "includes/nav.html" %}
{% endblock %}
</nav>
[...]
<nav class="mobile">
{% block mobile_nav %}
{% include "includes/nav.html" %}
{% endblock %}
</nav>
[...]
The include template depends on a variable called selected
, which base.html does not define, by default:
<!--includes/nav.html:-->
<a href="/about/" class="{% if selected == 'about' %}selected{% endif %}">About</a>
<a href="/people/" class="{% if selected == 'people' %}selected{% endif %}">People</a>
<a href="/contact/" class="{% if selected == 'contact' %}selected{% endif %}">Contact</a>
But child pages can override that value as follows:
<!--about.html:-->
{% extends "base.html" %}
{% block desktop_nav %}{% with selected='about' %}{{ block.super }}{% endwith %}{% endblock %}
{% block mobile_nav %}{% with selected='about' %}{{ block.super }}{% endwith %}{% endblock %}
so, not perfect, I still have to have two separate blocks and use those with
blocks twice, but it does allow me to override variables in include
blocks from the parent template.
- [Django]-Model not showing up in django admin
- [Django]-How to use subquery in django?
- [Django]-Using Basic HTTP access authentication in Django testing framework
5
It seems that the final template is trying to extend itself (if it was in quotes).
You really don’t need that much of complexity. It’s actually pretty much simpler.
The base template should hold the skeleton of your template, then you can extend it to make customizations. For reusable code blocks that you don’t want to include in your every view, include
them where appropriate but don’t use any block
, extends
or include
statement within the included file. Django will not parse those but the context variable
passed from the view can still be used.
- [Django]-How to make a PATCH request using DJANGO REST framework
- [Django]-Alternate Row Coloring in Django Template with More Than One Set of Rows
- [Django]-Cannot access django app through ip address while accessing it through localhost
2
In short, you can create variables in whichever template you’re planning to include e.g.
{{ localcontent }}
and then assign those variables wherever you include the template e.g.
{% include "name_snippet.html" with localcontent="Actual content" %}
- [Django]-How to encode UTF8 filename for HTTP headers? (Python, Django)
- [Django]-Best way to write an image to a Django HttpResponse()
- [Django]-How to combine multiple QuerySets in Django?
0
You could split reusable_pattern_template into begin and end templates. Then in level1 you can go include begin, block, include end.
Alternatively you could pass a template name into reusable_pattern_template as a context variable and then include it in reusable_pattern_template. This will require changing the relationship between level1 and level2 in your example but is generally more powerful.
- [Django]-How do I match the question mark character in a Django URL?
- [Django]-How to obtain and/or save the queryset criteria to the DB?
- [Django]-What is the advantage of Class-Based views?
0
Not the exact thing but you can do this (I’ve used it for including navigation bars):
Use with
and only
snippet.html
:
<div>
{{ listItem1 }}{{ listItem2 }}...{{ listItemN }}
</div>
index.html
:
{% include 'snippet.html' with listItem1='<li>HOME</li>' listItem2 ='<li>ABOUT</li>' only %}
Since, we have used only
after listItem2, all further variables will be ignored.
- [Django]-H14 error in heroku – "no web processes running"
- [Django]-Django-taggit – how do I display the tags related to each record
- [Django]-Any thoughts on A/B testing in Django based project?
0
I understand what you want to do, however, Django does not process blocks in included files… I have a "dirty" solution for you:
Let’s suppose you have:
initial_state
This won’t be possible since constants.html won’t be processed into a new about.html, which will be processed into base.html…
The "dirty" solution:
possible_solution
With this, you can re-use the same block as many times as you want, however you will create a new file for each of them…
- [Django]-Django equivalent of SQL not in
- [Django]-Get request data in Django form
- [Django]-Django – Website Home Page