Context是mako中的一个重要概念,负责模板与外界所有的数据传递。在模板中,我们可以用变量context来访问它。Context由两个重要组成部分组成,一个是类似StringIO的输出缓存buffer,另一个是存储参数(render参数、built-in参数等)的字典,该字典中的所有参数都可以直接在模板中使用。
from mako.template import Template
from mako.runtime import Context
from StringIO import StringIO
mytemplate = Template("hello, ${name}!")
buf = StringIO()
ctx = Context(buf, name="jack")
mytemplate.render_context(ctx)
print buf.getvalue()
1. 输出缓存
模板中所有的文本,${}包含的表达式,context.write()等方式都可直接将结果保存到Context中的输出缓存buffer中。不过尽量不要直接去操纵这个变量,因为在filter/cache等场景下中,该变量有可能会改变。
2. 参数字典
render传入模板的参数都会放入到context的参数字典中,在模板解析时,mako会判断一个变量是否已经被定义(如赋值),如果未定义,就会在模板开头从context中载入这个变量,如:
username = context.get('username', UNDEFINED)
因此,在模板中可以直接按名字引用context中存储的参数变量。
3. UNDEFINED
UNDEFINED是mako中定义的一个类mako.runtime.Undefined的一个实例,主要用于处理模板中可能会出现的未定义变量。不过因为UNDEFINED在转成字符串是是raise NameError("Undefined”),所以开发者看不出究竟是哪个变量没有定义。这给开发带来了一定的麻烦。因此,mako引入了strict_undefined参数,只要在Template、TemplateLookup中传入strict_undefined=True参数,那么mako遇到未定义变量将直接抛出NameError,如定义了strict_undefined=True之后,mako生成的代码是:
try:
mytest = context['mytest']
except KeyError:
raise NameError("'mytest' is not defined")
而不是
mytest= context.get('mytest', UNDEFINED)
不过如果希望在模板中自己去判断变量是否存在,那么就需要用类似:
% if someval is UNDEFINED:
someval is: no value
% else:
someval is: ${someval}
% endif
或
${'not defined' if someval is UNDEFINED else someval }
这种方式来判断了,这个时候就需要设置strict_undefined=False。
4. 模板之间的变量共享
前面提到了,在模板中定义的所有变量都是render_body的私有变量,因此如果需要在几个不同的模板之间(一次渲染请求中)共享某个参数,就需要使用context来进行传递了。
但上面也提到了context很有可能在一次渲染过程中,几个不同模板间会有不同,那么如何来做到变量的共享呢?
其实,我们可以在render的时候传入一个空的字典,不是None,是{},如:
output = template.render(attributes={})
接下来,我们就可以在模板中用如下方式来赋值、引用了:
<%
attributes['foo'] = 'bar'
%>
'foo' attribute is: ${attributes['foo']}
5、context常见使用方法
context是一个类似字典的数据结构,常见的一些用法如下:
* context[key] / context.get(key, default=None) 直接访问context中的参数字典
* keys() 得到context中所有参数名
* kwargs 得到context中所有参数的一份拷贝
* write() 写入到输出缓存
* lookup 得到TemplateLookup实例
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment