剖析Django中模版标签的解析与参数传递
分析直至另一个模板标签
模板标签可以像包含其它标签的块一样工作(想想{%if%}、{%for%}等)。要创建一个这样的模板标签,在你的编译函数中使用parser.parse()。
标准的{%comment%}标签是这样实现的:
defdo_comment(parser,token): nodelist=parser.parse(('endcomment',)) parser.delete_first_token() returnCommentNode() classCommentNode(template.Node): defrender(self,context): return''
parser.parse()接收一个包含了需要分析的模板标签名的元组作为参数。它返回一个django.template.NodeList实例,它是一个包含了所有Node对象的列表,这些对象是解析器在解析到任一元组中指定的标签之前遇到的内容.
因此在前面的例子中,nodelist是在{%comment%}和{%endcomment%}之间所有节点的列表,不包括{%comment%}和{%endcomment%}自身。
在parser.parse()被调用之后,分析器还没有清除{%endcomment%}标签,因此代码需要显式地调用parser.delete_first_token()来防止该标签被处理两次。
之后CommentNode.render()只是简单地返回一个空字符串。在{%comment%}和{%endcomment%}之间的所有内容都被忽略。
分析直至另外一个模板标签并保存内容
在前一个例子中,do_comment()抛弃了{%comment%}和{%endcomment%}之间的所有内容。当然也可以修改和利用下标签之间的这些内容。
例如,这个自定义模板标签{%upper%},它会把它自己和{%endupper%}之间的内容变成大写:
{%upper%} Thiswillappearinuppercase,{{user_name}}. {%endupper%}
就像前面的例子一样,我们将使用parser.parse()。这次,我们将产生的nodelist传递给Node:
defdo_upper(parser,token): nodelist=parser.parse(('endupper',)) parser.delete_first_token() returnUpperNode(nodelist) classUpperNode(template.Node): def__init__(self,nodelist): self.nodelist=nodelist defrender(self,context): output=self.nodelist.render(context) returnoutput.upper()
这里唯一的一个新概念是UpperNode.render()中的self.nodelist.render(context)。它对节点列表中的每个Node简单的调用render()。