2011-05-06 157 views
4

这似乎是一个非常基本的事情,但尽管我一直在使用Django大约一年,但我从未遇到过这种情况。嵌套Django模板

在很多模板/ web框架中,模板继承的工作方式有点不同,通常它的行为更像包装器,所以如果您有childtemplate.html,parenttemplate.html和grandparenttemplate.html,那么最终呈现通常看起来像这样:

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

这并不完全如何在Django中工作,但我想知道如何实现它。

具体我有我的“孩子”模板,我们只是说它是foo.htmlfoo.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 %} 

原本应该呈现为

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

if parent_template is set and

<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可能是空白的,然后有时候base.html文件将越来越刚刚child_content块,而不是content块。

此外,我希望能够做到这一点,而不必创建一堆子块(如果我决定foo应用程序应该有自己的/foo/base.html,然后调用/base.html)?

任何想法?

回答

9

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> 

使用父:

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

为您提供:

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

编辑:解决此问题

一个办法让嵌套块是:

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' %}标记的块,但看起来不太干燥。我很好奇看到其他人对嵌套块的反应。

+0

我知道发送可变参数的能力,事实上这就是我正在做的。我需要'

基开始

家长START

FOO

家长END

底端

'所以'{{block.super}}'是不会削减它,因为它只是把内容在顶部。 – 2011-05-06 20:29:12

+0

因为我认为这个想法很有趣,所以我对你的答案满意,但它仍然不是一个完整的答案。我肯定希望看到其他人的回应,如果有的话。 :) – 2011-05-09 14:40:11

+1

django需要整理出多个模板的继承,否则你应该如何为你的网站获得一个外观和感觉。因为这个,我的网站看起来不太干 – Sevenearths 2011-06-02 08:55:03