前两篇文章主要说明了web.py的模板系统将模板文件处理后得到的结果:__template__()
函数。本文主要讲述模板文件是如何变成__template__()
函数的。
一般来说,更常用的是Render类,该类会处理整个目录下的模板,还支持缓存和嵌套模板。不过这些其实都和模板本身的解析基本没关系,以后再说明这个类的实现和用途。这里我们使用frender()
函数:
12345 | def frender(path, **keywords): \”\”\”Creates a template from the given file path. \”\”\” return Template(open(path).read(), filename=path, **keywords) |
这个函数相当简单,只作了一键事情,就是读取模板文件内容,然后交给Template类处理,并且返回一个Template类实例。从这里也可以看出,整个模板的解析,只和Template类有关,frender是来打杂的。
当我们根据一个模板内容创建一个Template类实例t后,我们可以调用该实例,这相当于调用模板对应的__template__()
函数,得到的结果是一个TemplateResult实例。
1234567891011121314151617 | In [7]: t = web.template.frender(\”templates/hello.html\”)# coding: utf-8def __template__ (name): __lineoffset__ = –4 loop = ForLoop() self = TemplateResult(); extend_ = self.extend extend_([u\’hello, \’, escape_(name, True), u\’\\n\’]) return self In [8]: print t(\”xxxx\”)hello, xxxx In [9]: print type(t(\”xxxx\”)) <class \’web.template.TemplateResult\’> |
Template实例化过程是把模板转换成HTML内容的实质性步骤,不过这个过程比较复杂。但是,概括的来讲,这个过程和Template的__init__()
函数中的步骤差不都差不多。
1234567891011121314151617 | # Template类的__init__()函数def __init__(self, text, filename=\’\’, filter=None, globals=None, builtins=None, extensions=None): self.extensions = extensions or [] text = Template.normalize_text(text) code = self.compile_template(text, filename) _, ext = os.path.splitext(filename) filter = filter or self.FILTERS.get(ext, None) self.content_type = self.CONTENT_TYPES.get(ext, None) if globals is None: globals = self.globals if builtins is None: builtins = TEMPLATE_BUILTINS BaseTemplate.__init__(self, code=code, filename=filename, filter=filter, globals=globals, builtins=builtins) |
首先把,参数里除了text以外的参数忽略掉,然后来看下对text的处理过程(text就是模板的内容)。整个过程概括的说有如下步骤:
text = Template.normalize_text(text)
, 主要换行符统一成n,删除BOM字符串,将$替换成$$,这个就是简单的字符串处理。code = self.compile_template(text, filename)
,code就是之前已经提到过的__template__()
函数。__init__()
函数:创建__template__()
函数的执行环境,并且实现可调用功能。其他没有说明的代码,暂时都可以忽略,不会影响你理解Template的实例化过程。从上面的步骤可以看出,Template实例化的过程主要有两个:生成__template__()
函数的代码并编译,以及创建__template__()
函数的执行环境。
这个是模板生成过程中最长最复杂的一段,会应用到Python的token分析功能以及动态编译功能。还记得第一篇里,我们搭建实验环境的时候,修改了web.py源码,在一个地方插入了一行打印语句么?没错,就是这个compile_template()
函数,我们现在来看看它是如何生成__template__()
函数的代码的。
12345678910111213 | def compile_template(self, template_string, filename): code = Template.generate_code(template_string, filename, parser=self.create_parser())late_string, filename, parser=self.create_parser())支持缓存和嵌套模板。不过这些其实都和模板本身的解析基本没关系,以后再说明这个类的实现和用途。这里我们使用frender() 函数:
这个函数相当简单,只作了一键事情,就是读取模板文件内容,然后交给Template类处理,并且返回一个Template类实例。从这里也可以看出,整个模板的解析,只和Template类有关,frender是来打杂的。 Template类Template实例的效果当我们根据一个模板内容创建一个Template类实例t后,我们可以调用该实例,这相当于调用模板对应的
Template实例化过程Template实例化过程是把模板转换成HTML内容的实质性步骤,不过这个过程比较复杂。但是,概括的来讲,这个过程和Template的
首先把,参数里除了text以外的参数忽略掉,然后来看下对text的处理过程(text就是模板的内容)。整个过程概括的说有如下步骤:
其他没有说明的代码,暂时都可以忽略,不会影响你理解Template的实例化过程。从上面的步骤可以看出,Template实例化的过程主要有两个:生成 生成__template__()函数的代码这个是模板生成过程中最长最复杂的一段,会应用到Python的token分析功能以及动态编译功能。还记得第一篇里,我们搭建实验环境的时候,修改了web.py源码,在一个地方插入了一行打印语句么?没错,就是这个
|