我一直在努力学习更多关于Django模板引擎的知识,因为它对我来说似乎总是有点像黑盒子。 The documentation概括了所涉及的一般步骤,并指出模板已加载并解析,创建了一个节点树,它与一个上下文一起呈现(以级联形式?)并附加在一起以给出结果。
我不理解的是解析方法,以及创建节点的标准是什么?解析后构成特定节点的内容,以及如何影响自定义模板标记的创建(即,是否有更好,更有效的方法来编写模板标记,从而导致节点数量减少?)。
答案 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