2011-11-21 84 views
8

我一直在努力學習更多關於Django的模板引擎,因爲它總是對我來說像是一個黑盒子。 The documentation給出了所涉及的一般步驟的良好輪廓,並指示模板已被加載和解析,從而創建一個節點樹,該節點通過上下文呈現(級聯?)並附加在一起以提供結果。如何解析django模板?

我不明白的是解析的方法,在什麼標準下創建節點?在解析之後什麼構成了特定的節點,以及這會如何影響創建自定義模板標籤(即,是否有更好更有效的方式來編寫將導致節點更少的模板標籤?)。

+0

我開始讀'django.template.base',但是一旦我感覺到強大的時間彎曲魔法(就像goto 5am),就馬上走了出來。我會upvote和檢查在早上,而不是:) –

+0

我已經把它放在我的待辦事項列表! –

回答

2

我認爲你應該看的第一件事是code.djangoproject.com 與django/template/base.py - 第一個(如Yuji Tomita之前所述)。或者下載源代碼,並用你最喜歡的編輯器或IDE查看它。

3

瞭解更多關於該過程的一種方法是使用werkzeug debugger運行django,並在模板中觸發異常。這樣,您就可以查看(並與之交互)整個堆棧。

0

我猜他們使用的標記化和解析

一個簡單的方法來discribe是:

符號化: 突破APPART的代碼類型,如:

integer foo = "bar" + 15; 

這個由

T_VARIABLETYPE + T_VARIABLENAME + T_EQUALS + T_STRING + T_PLUS + T_DIGIT + T_SEMI 

之後你可以試着解析克至查找模式與解析器

解析:

找到模式:

T_VARIABLETYPE + T_VARIABLENAME + T_EQUALS + {A recursive thing} + T_SEMI 

這樣,如果你喜歡這個,我可以推薦將試驗可以執行命令

使用「ANTLR」http://www.antlr.org/ 它可用於很多不同的語言,如Java或C#甚至PHP和JS

3

節點是在每個標記之外創建的。您可以通過閱讀how to write custom tags瞭解它是如何工作的。標籤內的任何東西都是它的孩子。下面是來自Django文檔註釋標籤的例子:

def do_comment(parser, token): 
    nodelist = parser.parse(('endcomment',)) 
    parser.delete_first_token() 
    return CommentNode() 

正如你看到的註釋標記將解析一切直到「endcomment」,並把它扔掉。其他標籤將通過nodelistSometagNode()並將用於渲染。

呈遞是遞歸地完成的。當在節點上調用render()時,它會在其子節點上運行渲染,等等。

解析遞歸要做的事,這就是爲什麼你可以嵌套的標籤和parser.parse()將設法找到合適的匹配的結束標記,因爲當它在標籤上解析和絆它調用do_tag()的事情,這將依次調用parser.parse()再次找到最近的結束標記,並將所有內容都包裝到一個節點中,返回一個節點,較高級的parser.parse()會將它放到節點列表中並繼續搜索結束標記。

節點中的上下文對象是一種字典結構的列表。額外的上下文被推到現有的上下文之上,並被傳遞給子節點,並在節點被渲染後彈出,以便它不會影響範圍上限。

對於沒有孩子的標籤,不使用parser.parse(),所以節點實例返回時沒有任何孩子。