How to complement the block of parent template? - django

I have first.html:
{% block title %}
hi there
{% endblock %}
{% block content %}
blah-blah
{% endblock %}
{% block footer %}
bye
{% endblock %}
and second.html.
How can I incude all first.html page to second.html and complement content block like this:
hi there
blah-blah
this text is from second.html
bye
I've tryed
{% extends "first.html" %}
this text is from second.html
(just nothing added) and
{% extends "first.html" %}
{% block content %}
this text is from second.html
{% endblock %}
(block content is overrided).

You can make use of {{ block.super }} [Django-doc] here when you want to render the original content as well. For example:
{% extends 'first.html' %}
{% block content %}
{{ block.super }}
this text is from second.html
{% endblock %}

Related

Jinja html code gets incorrectly formatted when saved in VS code

I am writting a Django project using VS Code. I find a strange Jinja formatting issue.
What I want is
{% extends "../base.html" %}
{% load static %}
{% block title %}
{% if category %} {{ category.name }} {% else %} Products {% endif %}
{% endblock %}
{% block content %} {% endblock content %}
But when I save the file or ctrl+s, it gets formatted like
{% extends "../base.html" %} {% load static %} {% block title %} {% if category
%} {{ category.name }} {% else %} Products {% endif %} {% endblock %} {% block
content %} {% endblock content %}
and the render gets error due to broken brackets.
I am using Jinja2 Snippet Kit and Prettier plugins. Do I need to make some changes in setting?
Could someone give me a help? Thank you.

Nesting Django block with {% include %}

I am trying to nest blocks with Django 3. I have sections of html that are sometimes reused on a page. I don't think I would have to resort to duplicating templates, but I can't get it to work;
I have this template
{% extends 'base.html' %}
{% include 'site_part.html' %}
{% block content %}
Some Content
<br>
And here I insert the child content
{% block part_of_site %}
{% endblock %}
{% endblock %}
And the site_part_html is like this;
{% block part_of_site %}
Okay, i am loaded!
{% endblock %}
In the base.html I have only this:
{% block content %}
{% endblock %}
I'd expect it to render the "Okay, i am loaded!" string in the resulting page, in the content block. However, it remains empty. I've looked, but most examples are far more advanced then what I need and I can't get those to work either.
If I remove the extends statement at that start and the block content lines, it does load the included html.
Basically, I have a site part that sometimes is need, and I'd like to included that based on some templating. Otherwise, I'd have duplicate that code for each of the pages that it occurs on.
You may call the content from the block 'part_of_site' in any child template using {{ block.super }} like this:
{% extends 'site_part.html' %}
{% block content %}
Some Content
<br>
{% block part_of_site %}
{{ block.super }}
{% endblock %}
{% endblock %}
You should use {% extends 'base.html' %} in the 'site_part.html' template. All children of 'site_part.html' will also be a descendant of base.html
{% extends 'base.html' %}
{% block part_of_site %}
Okay, i am loaded!
{% endblock %}
If you want to use {% include %} instead, change your code like this:
{% extends 'base.html' %}
{% block content %}
Some Content
<br>
{% include 'site_part.html' %}
{% endblock %}
You need to move your {% include 'site_part.html' %} into the {% block content %} block.
content.html
{% extends 'base.html' %}
{% block content %}
Some Content
<br>
And here I insert the child content
{% include 'site_part.html' %}
{% block part_of_site %}
{% endblock %}
{% endblock %}
Then, in your view you need to return your content template. I named it content.html here.
def your_view(request):
return render(request, "content.html")
You can put the include anywhere inside the content block, it doesn't have to be right before the part_of_site block.

{% block something %} always being displayed despite being False in an if-statement

I have two types of blog articles. Regular blog articles, and translation articles. They both have different html markup. I have a boolean variable translation_bool in my models to check if it is a translation article or not. If it is I want it to display my {% block translation %} and if not {% block translation %}. It worked with plain html code and not using html tags. But I had so much reusable code that it got troublesome to manage.
So my question is: why is this happening despite it being inside of an if statement.
Article template:
{% extends "base_generic.html" %}
{% load static %}
{% block js %}...{% endblock %}
{% if blogpost.translation_bool == True %}
{% block translation %}....{% endblock %}
{% else %}
{% block content %}...{% endblock %}
{% endif %}
{% block sidebar %}....{% endblock %}
In Base Generic Template:
<div class="row">
<div class="col-md-1"></div>
<div class="col-md-8">
{% block content %}{% endblock %}
{% block translation %}{% endblock %}
</div>
<div class="col-md-3">
{% block social_media %}...{% endblock %}
{% block sidebar %}...{% endblock %}
</div>
</div>
</body>
This is because blocks not defined in child template will render value from parent template. So in your case you should perform validation inside parent template. Or if it's impossible override blocks in child with empty content:
{% block translation %}
{% if blogpost.translation_bool == True %}
{{ block.super }}
{% else %}
{% endif %}
{% endblock %}
{% block content %}
{% if blogpost.translation_bool == False %}
{{ block.super }}
{% else %}
{% endif %}
{% endblock %}
Note {{ block.super }} will render content from parent template.

Django templates inheritance

For example:
base.html
<body>
{% block content}
{% endblock %}
</body>
base_index.html
{% extends 'base.html' %}
{% block content %}
something
{% endblock %}
# add new block "for_child" to fill in with next inheritance
<h1>Name:
{% block for_child %}
{% endblock %}</h1>
base_index_child.html
{% extends 'base_index.html' %}
{% block for_child %}
Peter
{% endblock %}
Result base_index_child.html:
<body>
something
</body>
But i want (base.html -> base_index.html -> base_index_child.html)
<body>
something
<h1>Name: Peter</h1>
</body>
How to get this?
Update (answer)
Adding a block must be inside the block
base_index.html
{% extends 'base.html' %}
{% block content %}
something
<h1>Name:
{% block for_child %} # block must be inside the block
{% endblock %}</h1>
{% endblock %}
This post is pretty much what you're asking.
So this would fix it:
base_index.html
{% extends 'base.html' %}
{% block content %}
something
<h1>Name:
{% block for_child %}
{% endblock %}
</h1>
{% endblock %}

Django overwrite parts in inherited templates

I have set up the following templates
base.html
{% extends 'base/main_base.html' %}
{% block main-content %}
<h1>Header stuff<h1>
...
{% block article-content %}
{% endblock %}
{% endblock %}
article.html
{% extends 'base.html' %}
{% block article-content %}
<h2>Content</h2>
<p>More content</p>
{% endblock %}
Now, I connected a view to the article.html, and I want use the dynamic view data to overwrite the 'header stuff' in the 'base.html' template. Problem is, the view is connected to the article.html, which inherits from the base.
Is there a way to override parts of the base template from the child template?
You could create another template block in your base.html
{% extends 'base/main_base.html' %}
{% block main-content %}
<h1>{% block header %}Header stuff{% endblock %}<h1>
...
{% block article-content %}
{% endblock %}
{% endblock %}
and overwrite the block in your article.html
{% extends 'base.html' %}
{% block header %}My overwritten headline{% endblock %}
{% block article-content %}
<h2>Content</h2>
<p>More content</p>
...
{% endblock %}
You could also check, in base.html, if a "header" value is injected to the template from the article (or any other view):
base.html
{% extends 'base/main_base.html' %}
{% block main-content %}
<h1>
{% if header %}
{{ header }}
{% else %}
Header stuff
{% endif %}
<h1>
...
{% block article-content %}
{% endblock %}
{% endblock %}