Вложенные шаблоны django

это кажется довольно простой вещью, но, хотя я использую Django около года, я еще никогда не сталкивался с этим сценарием.

во многих шаблонах / веб-фреймворках наследование шаблонов работает немного иначе, в том, что обычно оно ведет себя больше как обертки, поэтому, если у вас есть childtemplate.HTML-код, parenttemplate.html и grandparenttemplate.html, то, наконец, рендеринг обычно выглядит примерно так:

grandparent header
    parent header
        child header
        child content
    parent content
    parent footer
grandparent content
grandparent footer

это не совсем так работает в Django, но мне интересно как это реализовать.

в частности, у меня есть шаблон "ребенок", скажем так, это foo.html. foo.html дополнительно получает переменную parent_template или по умолчанию " base.HTML-код"

{% extends parent_template|default:"base.html" %}

{% block content %}
I am a foo and my title is {{ foo.title }}
{% endblock content %}

Итак, здесь я сталкиваюсь с проблемой. Если parent_template является шаблоном, этот шаблон должен обернуть содержимое foo.html а затем поместите результат в base.html:

{% extends "base.html" %}

{% something_magical_here %}
<div>parent header</div>
# content of foo.html
<div>parent footer</div>
{% end_something_magical_here %}

а потом в base.html:

<html>
... snip ...
<div id="content">
{% something_else_magical %}
# content of parent_template rendering, or just foo.html if no parent_template given
{% end_something_else_magical %}

что должен render as

<html>
... snip ...
<div id="content">
<div>parent header</div> 
I am a foo and my title is Bar
<div>parent footer</div>

если parent_template установлен и

<html>
... snip ...
<div id="content">
I am a foo and my title is Bar

если это не так.

я надеюсь, что моя проблема ясна: мне нужно (необязательно) обернуть шаблон в родительский шаблон, а затем отправить результаты этого в base.html шаблон.

обычно что-то вроде этого может работать:

#foo.html
{% extends "parent.html" %}
{% block child_content %}
I am a foo and my title is {{ foo.title }}
{% endblock child_content %}

#parent.html
{% extends "base.html" %}

{% block content %}
parent header
{% block child_content %}{% endblock child_content %}
parent content
parent footer

#base.html
base header
{% block content %}{% endblock content %}
base content
base footer

однако, поскольку parent_template может быть пустым, то иногда базовым.html будет получать только child_content блок, а не content блок.

кроме того, я хотел бы иметь возможность сделать это без необходимости создавать кучу подблоков (что, если я решу, что foo приложение должно иметь свой собственный /foo/base.html что то называет /base.html)?

какие идеи?

1 ответов


тег шаблона extends может принимать аргумент переменной.

так:

base.html
    {% block content %}
        <p>BASE</p>
    {% endblock %}

parent.html
    {% extends "base.html" %}

    {% block content %}
        {{ block.super }}
        <p>PARENT</p>
    {% endblock %}

foo.html
    {% extends ext_templ %}

    {% block content %}
        {{ block.super }}
        <p>FOO</p>
    {% endblock %}

используя основание:

return render_to_response('foo.html', {'ext_templ':'base.html'})

дает вам:

<p>BASE</p>
<p>FOO</p>

использование parent:

return render_to_response('foo.html', {'ext_templ':'parent.html'})

дает вам:

<p>BASE</p>
<p>PARENT</p>
<p>FOO</p>

edit:

один из способов обойти эту проблему, чтобы получить вложенные блоки:

base.html
    {% block content %}
        {% block top %}
            <p>BASE START</p>
        {% endblock %}

        {% block bot %}
            <p>BASE END</p>
        {% endblock %}
    {% endblock %}


parent.html
    {% extends "base.html" %}

    {% block top %}
        {{ block.super }}
        <p>PARENT</p>
    {% endblock %}

    {% block bot %}
        <p>PARENT</p>
        {{ block.super }}
    {% endblock %}

foo.html
    {% extends ext_templ %}

    {% block top %}
        {{ block.super }}
        <p>FOO</p>
    {% endblock %}

    {% block bot %}
        <p>FOO END</p>
        {{ block.super }}
    {% endblock %}

другой метод, который я могу придумать, - это обернуть блоки {% if ext_templ == 'parent.html' %} тег, но это, кажется, не очень сухой. Мне любопытно увидеть, как другие народы реагируют на вложенные блоки.