Jinja2: How to use named blocks inside included templates, inside extendable template

Jasim Muhammed picture Jasim Muhammed · Feb 12, 2014 · Viewed 14.3k times · Source

I am having the Issue with Jinja2 Extend and Import.

base_admin.html

<html>
<body>
    <div class="outerbody">
        <somehtml code>
        {% include "base_admin_nav.html" %}
        {% include "base_admin_sidebar.html" %}            
        {% include "base_admin_content.html" %}
    </div>
</body>
</html>

base_admin_content.html

<div class="innerbody">
    {% block body_content %}
    {% endblock %}
</div>

admin.html

{% extends 'base_admin.html' %}
{% block body_content %}
    <div>BodyContent</div>
{% endblock %}

The code inside body_content is not passed to base_admin_content.html. Any workarounds?

Note

This is not duplicate of this one jinja2: blocks in included files.. The include is done in different files here

Defining {% macro admin_content() %} insdide base_admin_content.html and importing it inside base_admin.html using

{% from "base_admin_content.html" import admin_content with context %}
        {{ admin_content() }}.

also has no effect.

Answer

Quentin Donnellan picture Quentin Donnellan · Feb 12, 2014

Edited - to reflect changes in original question

Ok, now that I know you definitely need the includes, here's how I would do it: instead of including the base_admin_content.html file, you should include the admin.html file directly into base_admin.html. The admin.html file will extend base_admin_content.html and everything should work just fine:

base_admin.html

<html>
<body>
    <div class="outerbody">
        <somehtml code>
        {% include 'admin.html' %}
    </div>
</body>
</html>

admin.html

{% extends 'base_admin_content.html' %}
{% block body_content %}
    <div>BodyContent</div>
{% endblock %}

base_admin_content.html

{% block innerbody %}
<div class="innerbody">
    {% block body_content %}
    {% endblock %}
</div>
{% endblock %}

Why does this work but your original code does not?

In your base_admin.html file you have

{% include 'base_admin_content.html' %}

Where we have no reference to admin.html, which is why nothing from the admin.html file shows up!. Therefore, we should do this:

{% include 'admin.html' %}

Because that does contain a reference to base_admin_content in the extends line:

{% extends 'base_admin_content.html' %}

Hopefully that makes sense...