2009-12-12 78 views
20

我有這種風格的模板Django的:傳遞參數父模板

project 
- main_templates (including nav bar) 
-- app1 
--- app1_base_template 
--- app1_templates 
-- app2 
--- app2_base_template 
--- app2_templates 

所以渲染時,app2_templates延伸app2_base_template延伸main_template。

我需要做的是在app2的模板被渲染時顯示相應的導航項目(用於顯示用戶在哪裏)。

如果我可以在{%block xxx%}部分中傳遞一個變量,那麼最容易。 這可能嗎?

還有什麼其他的通用方法?

+0

你檢查了嗎? http://stackoverflow.com/questions/1024168/django-is-there-a-better-way-to-bold-the-current-page-link – rinti

+2

該CSS解決方案看起來很難維護,並需要添加信息在3個不同的地方。 – Boris

回答

41

您是否嘗試了{%with%}模板標記?

{% block content %} 
    {% with 'myvar' as expectedVarName %} 
    {{block.super}} 
    {% endwith %} 
{% endblock content %} 
+0

對不起,不要這樣做。這是在base.html,是'block.super'旨在引用navbar ...?我的導航欄中包含了我的導航欄,*然後是我的「塊內容」...應該如何設置此功能? – Pureferret

+3

有趣的黑客,但不是一個完整的解決方案。父模板需要大部分都被'{%block content%}'包圍,這樣才能工作,並且這可以防止我在'content'內覆蓋另一個塊。 – Kos

+0

在Django 1.11+中更改了語法,即使仍然支持舊語法:https://docs.djangoproject.com/en/1.11/ref/templates/builtins/#with。{%with'myvar'as expectedVarName% } => {%with expectedVarName ='myvar'%} – ThePhi

2

來自父模板的變量會自動包含在子範圍中。你的標題說你想傳遞一個變量給父母,這是沒有道理的,因爲你不能在模板中定義變量。如果你需要父變量和子變量,只需在視圖中聲明它。

8

沒有直接的方法來按照您描述的方式向模板繼承樹傳遞變量。人們實現導航欄的方式突出顯示當前頁面,這通常會根據網站本身的性質進行調整。這就是說,我已經看到了兩種常用的方法:

技術含量低的方法

中,表示該選項卡已激活模板的上下文傳遞一個變量:

# in views.py 
def my_view(request): 
    return render_to_response('app2_template.html', {"active_tab": "bar"}, 

<!-- Parent template --> 
<div id="navigation"> 
    <a href="/foo" {% ifequal active_tab "foo" %}class="active"{% endifequal %}>Foo</a> 
    <a href="/bar" {% ifequal active_tab "bar" %}class="active"{% endifequal %}>Bar</a> 
</div> 

越高技術方法

實施custom template tag呈現您的導航欄。讓標籤採用一個變量,指示哪一部分是活動的:

<!-- Parent template --> 

<div id="navigation">{% block mainnav %}{% endblock %}</div> 

<!-- any child template --> 
{% load my_custom_nav_tag %} 
{% block mainnav %}{% my_custom_nav_tag "tab_that_is_active" %}{% endblock %} 

您可以從那裏瘋狂地發瘋。您可能會發現某人已經在djangosnippets.org上實施了一些適合您的功能。

+0

+1爲高科技方法。帶我進行了一些研究,以使其能夠奏效,提供一些詳細說明和參考資料,說明將來哪些文件可以幫助某些人。 – SpiRail

1

可悲的是我找不到一個乾淨的方式。

最後決定將標籤中的每個應用的base.html文件:(。其實我用兩個一組由應用程序的基本主導航一個由應用頁面的應用程序的導航欄設置)

<span class="main_nav_bar_hint" id="2"></span> 

,並在項目有點JQuery的魔法base.html文件

$(document).ready(function() { $("#nav_menu_" + $(".main_nav_bar_hint").attr("id")).removeClass("normal").addClass("selected"); }) 

它是一個黑客攻擊的一位,但這樣一來它很容易理解,我只需要做出合乎邏輯的變化,一旦加入更多的應用程序。

2

無法在模板包含中傳遞參數是Django模板系統的許多缺陷之一。

我不得不處理幾乎相同的問題:深層嵌套的模板需要使父模板以不同的方式進行格式化/高亮顯示。

可能的解決方案:

  1. 使用「超級語境」程序,其基於在地方層級你是在一個數量的值。即super_context = MySuperContext(request,other,values等),其中super_context是一個字典,您傳遞給視圖(或RequestContext)。這是最常用的Django-thionic(?)方法,但這意味着表示邏輯已被推回到視圖中,這對我來說是錯誤的。

  2. 使用expr模板標籤在較低級別的模板中設置值。注意:這僅適用於{%include%}模板,因爲它必須在包含發生之前進行評估。你不能用{%extends%}來做到這一點,因爲這必須是子模板中的第一件事。

  3. 切換到Jinja2模板,至少對於您需要這樣做的意見。

一旦你有這些值設定,你可以做這樣的事情:

<div class="foo{% if foo_active%}_active{%endif%}"> stuff </div> 

這使得DIV類「富」時,它不是主動和「foo_active」當它。風格品嚐,但不要添加太多肉桂。 :-)

2

我已賈勒特哈迪的「低技術」的做法類似的,呃...上下文(是的,這是一個雙關語......這不會使絕對意義上你,除非我告訴你,我沒有做導航,但設置了按鈕的邊框顏色以顯示哪個按鈕被按下)。

但我認爲我的版本更緊湊。我不是隻在視圖中定義一個簡單的上下文變量activebar,而是返回一個字典,但始終只有一個鍵值對:例如activebar = {'foo':'active'}。

然後在模板中,我簡單地在foo錨點中寫入class =「{{activebar.foo}}」,並相應地在其他錨點中寫入class =「{{activebar.foo}}」。如果只有activebar.foo被定義爲具有「active」值,那麼bar錨點中的activebar.bar將不會執行任何操作。也許「默默地失敗」是恰當的Django談話。鮑勃是你的叔叔。

編輯︰哎呀......一兩天過去了,雖然我上面寫的東西確實爲我工作的問題出現了,當我把一個新的窗口作爲目標放入導航欄的錨點。這似乎是一個奇怪的故障的原因:在點擊新窗口(Firefox中的選項卡),然後返回到啓動新窗口的那個窗口後,當我快速移動窗口時,導航欄下面的部分顯示爲空白光標在導航欄上的項目---沒有點擊任何東西。我不得不通過移動滾動條來強制屏幕重繪(不是頁面重新加載,儘管這也起作用,因爲它涉及屏幕重繪)。

我太過分了,不知道爲什麼可能會發生。而且有可能我做了一些其他的事情,導致不知怎麼的事情消失了。但是...我發現了一個更簡單的方法,對我來說非常合適。我的情況是,從視圖中啓動的每個子模板都應該使關聯的導航欄項目顯示爲「活動」。事實上,那個navbar項目是啓動了啓動子模板的視圖 - 通常的交易。

我的解決方案---讓我們以「登錄」導航欄項爲例---將其放入包含登錄窗體的子模板中。

{% block login %}active{% endblock %} 

我把它放在標題欄下面,但我不認爲這個位置是重要的。然後,在包含導航欄定義,圍繞在登錄導航欄項目,我把錨...好LI標記,這裏的父模板的代碼:

<li class="{% block login %}{% endblock %}"><a href="/mysite/login">Login</a></li> 

因此,當子模板被渲染的父母會將登錄導航欄項目顯示爲活動狀態,而Bob仍然是您的叔叔。

我上面描述的字典方法是顯示哪一行按鈕被按下,當它們都在同一個子模板上​​時。這仍然適用於我,因爲只涉及一個兒童模板,我不明白我的新的navbars方法在這種情況下會如何工作。請注意,使用navbars視圖的新方法甚至不涉及。簡單!