2012-03-09 27 views
28

我有一些html結構可以在很多不同的地方重複使用。它與整體模板不同,所以我不能擴展它,它也可以用來包含複雜的內容,所以我不認爲將它定義爲模板標籤是一件好事。以下是一些僞代碼,描述了我的期望結果,當使用template_level2.html時,您可以通過調用其中的塊來輕鬆地將內容放入reusable_pattern_template中。如果我確實使用了這個代碼,那麼您在template_level_2.html的「實際內容」中編寫的內容就不會顯示出來。我應該如何處理這個問題?django:在包含的模板中使用塊

base.html文件

<html> 
<head></head> 
<body> 
{% block content %}{% endblock %} 
</body> 
</html> 

template_level1.html

{% extends 'base.html' %} 
{% block content %} 
    Something here... 
    {% include 'reusable_pattern_template.html' %} 
    Something else here... 
{% endblock %} 

reusable_pattern_template.html

<div> 
    <div> 
    <div> 
     {% block local_content %}{% endblock %} 
    </div> 
    </div> 
</div> 

template_level2.html

{% extends 'template_level1.html' %} 
{% block local_content %} 
    Actual content here... 
{% endblock %} 

更新: 抱歉,在template_level2.html延伸有一些拼寫錯誤,我只是糾正它。

它可能不是很清楚,但上面的代碼中更多的是描述我所希望的結果的僞代碼。總之,

  • 我想在我的 模板中包括可重複使用的html模式的小塊。
  • 這些圖案就像是盒子,您可以將整個HTML 內容放入其中。所以上下文變量可能有點太有限 我的目的
+0

似乎永遠不會調用'template_level2.html'。如果你包含了一些代碼塊,你不需要使用'block'語句,因爲你將包括什麼時候以及你想要什麼 – 2012-03-09 12:13:41

+0

嗨fastreload! 'template_level2.html'是模板的最終級別,所以它不被包含/擴展到任何地方。通過調用'template_level2.html'中的'{%block%}'語句,我打算將內容放入''template_level2.html'中使用的'reusable_pattern_template.html'中。 – 2012-03-09 12:49:58

+0

問題:爲什麼不使用django-generic-flatblocks?這是一個很棒的應用程序,它提供了一個很棒的模式 – jpic 2012-03-09 13:33:34

回答

40

Django不處理包含文件中的塊。

包含標籤應被視爲「呈現此子模板幷包含HTML」的實現,而不是「解析此子模板並將其內容視爲其父項的一部分」。這意味着包含模板之間不存在共享狀態 - 每個包含都是完全獨立的呈現過程。 (Django template tag documentation

+7

儘管如此,來自視圖的變量仍然是共享和解析的。 – 2012-03-09 22:41:03

+0

上下文也被賦予包含的模板(這可能與上面的註釋相同,但'上下文'比視圖中的變量更容易識別。) – 2013-10-20 16:27:49

+7

有幫助的解釋,但是_is_有一個標記或其他方法來執行OP希望?我也希望能夠包含模板,並且仍然能夠使用模板繼承 – Ben 2014-08-08 22:04:10

3

看來,最終的模板正試圖擴展其本身(如果它是在引號)

你真的不需要那麼多的複雜性。它實際上非常簡單。

基本模板應該保存模板的骨架,然後可以擴展它以進行自定義。對於你不想在你的每個視圖包括,include他們在適當情況下,但不包含的文件中使用任何blockextendsinclude聲明可重用的代碼塊。 Django不會解析那些,但從視圖傳遞的context variable仍然可以使用。

0

您可以將reusable_pattern_template分割爲開始和結束模板。然後在level1中你可以去include begin,block,include end。

或者,您可以將模板名稱作爲上下文變量傳遞給reusable_pattern_template,然後將其包含在reusable_pattern_template中。這將需要在您的示例中更改level1和level2之間的關係,但通常更強大。

1

我遇到了這個問題,最終導致了下面的妥協,希望別人會覺得它有用。它依靠在子模板中使用with塊。

base.html文件想重用一個共同nav.html包括但定義一些區塊,其中內nav.html變量可能是由子模板被重寫。

<!-- base.html: --> 
<html> 
    [...] 
    <nav class="desktop"> 
    {% block desktop_nav %} 
     {% include "includes/nav.html" %} 
    {% endblock %} 
    </nav> 
    [...] 
    <nav class="mobile"> 
    {% block mobile_nav %} 
     {% include "includes/nav.html" %} 
    {% endblock %} 
    </nav> 
    [...] 

的包括模板依賴於一個名爲selected變量,它base.html文件沒有定義,默認爲:

<!--includes/nav.html:--> 
<a href="/about/" class="{% if selected == 'about' %}selected{% endif %}">About</a> 
<a href="/people/" class="{% if selected == 'people' %}selected{% endif %}">People</a> 
<a href="/contact/" class="{% if selected == 'contact' %}selected{% endif %}">Contact</a> 

但子頁面可以按如下覆蓋該值:

<!--about.html:--> 
{% extends "base.html" %} 
{% block desktop_nav %}{% with selected='about' %}{{ block.super }}{% endwith %}{% endblock %} 
{% block mobile_nav %}{% with selected='about' %}{{ block.super }}{% endwith %}{% endblock %} 

所以,不完美,我仍然必須有兩個獨立的塊,並使用這些with塊兩次,但它確實允許我從父模板的include塊中覆蓋變量。