在Python的Django框架中编写编译函数
当遇到一个模板标签(templatetag)时,模板解析器就会把标签包含的内容,以及模板解析器自己作为参数调用一个python函数。这个函数负责返回一个和当前模板标签内容相对应的节点(Node)的实例。
例如,写一个显示当前日期的模板标签:{%current_time%}。该标签会根据参数指定的strftime格式(参见:http://www.djangoproject.com/r/python/strftime/)显示当前时间。首先确定标签的语法是个好主意。在这个例子里,标签应该这样使用:
<p>Thetimeis{%current_time"%Y-%m-%d%I:%M%p"%}.</p>
注意
没错,这个模板标签是多余的,Django默认的{%now%}用更简单的语法完成了同样的工作。这个模板标签在这里只是作为一个例子。
这个函数的分析器会获取参数并创建一个Node对象:
fromdjangoimporttemplate register=template.Library() defdo_current_time(parser,token): try: #split_contents()knowsnottosplitquotedstrings. tag_name,format_string=token.split_contents() exceptValueError: msg='%rtagrequiresasingleargument'%token.split_contents()[0] raisetemplate.TemplateSyntaxError(msg) returnCurrentTimeNode(format_string[1:-1])
这里需要说明的地方很多:
每个标签编译函数有两个参数,parser和token。parser是模板解析器对象。我们在这个例子中并不使用它。token是正在被解析的语句。
token.contents是包含有标签原始内容的字符串。在我们的例子中,它是'current_time"%Y-%m-%d%I:%M%p"'。
token.split_contents()方法按空格拆分参数同时保证引号中的字符串不拆分。应该避免使用token.contents.split()(仅使用Python的标准字符串拆分)。它不够健壮,因为它只是简单的按照所有空格进行拆分,包括那些引号引起来的字符串中的空格。
这个函数可以抛出django.template.TemplateSyntaxError,这个异常提供所有语法错误的有用信息。
不要把标签名称硬编码在你的错误信息中,因为这样会把标签名称和你的函数耦合在一起。token.split_contents()[0]总是记录标签的名字,就算标签没有任何参数。
这个函数返回一个CurrentTimeNode(稍后我们将创建它),它包含了节点需要知道的关于这个标签的全部信息。在这个例子中,它只是传递了参数"%Y-%m-%d%I:%M%p"。模板标签开头和结尾的引号使用format_string[1:-1]除去。
模板标签编译函数必须返回一个Node子类,返回其它值都是错的。