如何解析django模板?

时间:2011-11-21 23:57:36

标签: django django-templates

我一直在努力学习更多关于Django模板引擎的知识,因为它对我来说似乎总是有点像黑盒子。 The documentation概括了所涉及的一般步骤,并指出模板已加载并解析,创建了一个节点树,它与一个上下文一起呈现(以级联形式?)并附加在一起以给出结果。

我不理解的是解析方法,以及创建节点的标准是什么?解析后构成特定节点的内容,以及如何影响自定义模板标记的创建(即,是否有更好,更有效的方法来编写模板标记,从而导致节点数量减少?)。

4 个答案:

答案 0 :(得分:3)

了解有关该过程的更多信息的一种方法是使用werkzeug debugger运行django,并在模板中触发异常。这样,到目前为止,您将能够查看(并交互)整个堆栈。

答案 1 :(得分:3)

从每个标记创建节点。通过阅读how to write custom tags,您可以了解其工作原理。标签内的任何东西都是它的孩子。以下是django docs的评论标记示例:

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

如您所见,评论标记将解析所有内容,直到" endcomment"并将它扔掉。其他代码会将nodelist传递给SometagNode()并将其用于呈现。

渲染以递归方式完成。在节点上调用render()时,它会在子节点上运行渲染,依此类推。

解析也是递归完成的,这就是为什么你可以获得嵌套标签,parser.parse()将设法找到正确匹配的结束标记,因为当它在标记上进行解析和绊倒时,它会调用do_tag()然后,它会再次调用parser.parse()来查找最近的结束标记并将所有内容包装到一个节点中,返回一个节点,更高的parser.parse()会将它放在一个节点列表上并继续搜索结束标记。

节点中的上下文对象是一种dicts结构列表。额外的上下文被推送到现有上下文之上并传递给子节点,并在呈现节点后弹出,这样它就不会影响上限。

对于没有孩子的标签,不使用parser.parse(),因此返回的节点实例没有任何子节点。

答案 2 :(得分:2)

我认为你首先要看的是code.djangoproject.com 与django / template / base.py - 第一个(如Yuji Tomita之前所述)。或者下载源代码并使用您喜欢的编辑器或IDE进行查看。

答案 3 :(得分:0)

我猜他们使用标记化和解析

一种简单的描述方式是:

标记化: 将代码分解为类似的类型:

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