scaffold的生成物雖然用處不大,但是給我們帶來一些最佳實踐。其中就有模板的繼承和分區。
如果你深入使用過rails的模板體系,那么恭喜你:你有超強的忍耐力!而且更重要的是,你只需要3分鍾就可以理解Django的模板體系。
讓我們先回顧一下rails的模板系統:
1. 你創建了一個xxxview,展現出一些數據。
2. 你意識到,各個view都有一些共同的內容。因為rails也強調DRY,所以你決定將這些共同的部分抽取出來。rails也看到了這點,所以你很高興的看到,rails支持layout。
3. rails的layout很簡單,類似html的代碼,<%= yield %>部分會被具體視圖替代,於是你很欣慰。
4. 但是等等,如何指定layout?你又興奮地發現:默認的layout是views/layouts/application.html.erb,你可以在controller、action去指定特定的layout,甚至這種指定支持變量。在興奮之余,你完全忽視了這等於讓controller去做了view該做的事情。
5. 你實現了一個左右結構的layout,左側是導航,右側是內容。你認為這個layout應該可以被多個view使用。但是你又發現不同的view需要的導航是不同的。由於存在幾個view使用一種導航、另外幾個view使用另一個導航的情況,由於DRY,rails說,我有partial。在view中可以使用<%= render "foo/bar" %>,甚至可以使用變量:
controller/action中指定具體的partial。:render :partial => ’foo/bar’。盡管,controller更進一步干預了view的細節;盡管,你又要記住:partial: foo/bar 意味着 views/foo/_bar.html.erb.<%= render @mypartial %>然后在
6. 如果view中的多塊內容要插到layout的不同地方怎么辦?除了主要的內容外,你還可以在view中定義:
然后這些內容塊會分別插入到layout的<%= yield :foo %> <%= yield :bar %> 和<%= yield %>的地方。
7. 還有,還有,<%= stylesheet_link_tag "application" %>, <%= javascript_include_tag "html5" %> ……
到這里,你可以說自己已經了解rails的模板系統了嗎?
接下來我們可以放松心情了,因為Django的模板很容易理解,除了基本的變量、標簽、過濾器等之外,模板的關系只有兩個:
1. 包含。將模板中的相同部分提取出來共用。
可以使用硬編碼的字符串{% include ’foo/bar.html‘ %} 或者變量名 {% include template_name %},變量當然是在view中賦值(注意,不是controller中)
2. 繼承。 模板繼承是Django解決共用頁面區域DRY的一個優雅的解決方案。簡單地說就是先構造一個基礎框架模板,而后在其子模板中對它所包含站點公用部分和定義塊進行重載(override)。基礎模板中,將內容不同的部分指定各個內容塊:
... {% block foo %} <div>default content of foo</div> {% endblock %} ... {% block bar %} <div>default content of bar</div> {% endblock %} ...
在子模板中指定繼承關系並override各個內容塊即可。繼承的寫法是{% extends "base.html" %}, 注意一定要放在模板的開頭部分。
好了,你已經理解了Django的模板系統,下面對產品清單界面的改造就非常容易理解了。分成兩個部分:base和productlist。
抱歉,寫到這里,發現篇幅已經不短了。只好界面的實現放到下一節了。