22

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.

Community
  • 1
  • 1
Jasim Muhammed
  • 1,376
  • 1
  • 20
  • 28

2 Answers2

8

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...

Quentin Donnellan
  • 2,687
  • 1
  • 18
  • 24
  • Thanks for your suggestion. Sorry I oversimplified the code.. now added the Edit. There are also many files I needed to include. I can't use the extend like that.. – Jasim Muhammed Feb 13 '14 at 04:47
  • Please see the ticket also http://stackoverflow.com/questions/1976651/multiple-level-template-inheritance-in-jinja2 – Jasim Muhammed Feb 13 '14 at 06:55
  • Ok, I see what you mean now - I've changed my answer to fit a bit closer to what you are asking for. In short - you should include `admin.html` not `base_admin_content.html` – Quentin Donnellan Feb 13 '14 at 18:04
  • this answer is weird because it missed the point of OP's template structure. Why would you `include admin.html` in `base_admin.html`? Is inverted. So youhave base_admin.html as general structure, admin.html as specific customizations, and `base_admin_content` as partial of the base_admin page. – est Mar 31 '19 at 15:40
0

You could inherit from base_admin and base_admin_content separately:

base_admin.html:

<html>
<body>
    <div class="outerbody">
        ...
        {% block admin_content %}
            {% include "default_admin_content.html" %}
        {% endblock %}
    </div>
</body>
</html>

base_admin_content.html: (unchanged)

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

admin.html:

{% extends 'base_admin.html' %}

...
{% block admin_content %}
    {% include "admin_content.html" %}
{% endblock %}

admin_content.html:

{% extends 'base_admin_content.html' %}

{% block body_content %}
    <div>BodyContent</div>
{% endblock %}

This way base_admin doesn't need to know about base_admin_content's blocks, it's flexible and simple.

Tim Diels
  • 3,246
  • 2
  • 19
  • 22