2011-05-06 158 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