Mako 模板系统Word文档格式.docx
- 文档编号:20473552
- 上传时间:2023-01-23
- 格式:DOCX
- 页数:42
- 大小:51.65KB
Mako 模板系统Word文档格式.docx
《Mako 模板系统Word文档格式.docx》由会员分享,可在线阅读,更多相关《Mako 模板系统Word文档格式.docx(42页珍藏版)》请在冰豆网上搜索。
只要加一个参数module_directory即可做到这一点:
module_directory='
/tmp/mako_modules'
当上述代码被render的时候,会创建文件
/tmp/mako_modules/docs/mytmpl.txt.py.下一次Template对象被用同样参数调用的时候,就会直接重用该模块文件。
2使用TemplateLookup
在模板中,我们有时候需要调用或引用其他模板的内容,这就牵涉一个模板查找定位的问题,通常用简单的URI字符串来定位。
我们用TemplateLookup
类来负责这个任务。
该类的构造函数需要传递一系列可供查找模板的路径的列表。
然后我们再将此TemplateLookup对象用关键字参数的形式传递给Template对象。
frommako.lookupimportTemplateLookup
mylookup=TemplateLookup(directories=['
/docs'
])
<
%includefile="
header.txt"
/>
helloworld!
lookup=mylookup)
上述例子中创建了一个文本模板,其中有一个对header.txt文件的包含引用。
而从何处去查找header.txt,则由TemplateLookup指明,是"
/docs"
目录。
通常,应用程序会把模板用文本文件的形式保存在文件系统中。
而为了方便起见,我们可以直接通过TemplateLookup来获取模板对象,利用TemplateLookup的get_template方法,并传递模板的URI作为参数:
],module_directory='
defserve_template(templatename,**kwargs):
mytemplate=mylookup.get_template(templatename)
printmytemplate.render(**kwargs)
lookup在查找模板时通过向其中的每一个搜索路径附加我们提供的模板URI的方式,来尝试获取模板文件。
如果找不到则引发TopLevelNotFound异常,这是一个Mako的自定义异常类型。
当lookup找到模板时,它还会给Template指定一个uri属性,这个uri就是传递给get_template()方法的参数。
Template可以用此uri来计算出其对应的模块文件的名称。
比如在上述例子中,/etc/beans/info.txt这个URI名称参数,会导致创建模块文件/tmp/mako_modules/etc/beans/info.txt.py.
3设定集合的大小
TemplateLookup同时也会在内存中缓存一组模板,所以并不是每一次请求都会导致模板的重新编译和模块重新加载。
默认TemplateLookup的大小没有限制,但你可以通过collection_size参数来限制它:
],
module_directory='
collection_size=500)
以上的lookup会持续加载模板到内存中,直到达到500的时候,它就会清除掉一定比例的模板缓存项,根据“最近最少访问”原则。
4设置文件系统检查
另一个TemplateLookup相关的标志是
filesystem_checks.默认为True,每一次get_template()方法返回模板后,原始的模板文件的revisiontime会和上次加载模板的时间做对比,如果文件更新,则会加载其内容,并重新编译该模板。
在生产环境下,设置filesystem_checks为False可以带来一定的性能提升(和具体的文件系统有关)。
5使用Unicode和Encoding
Template
和
TemplateLookup
都可以接受
output_encoding
encoding_errors
参数,用来对输出以Python支持的任何方式进行编码:
],output_encoding='
utf-8'
encoding_errors='
replace'
mytemplate=mylookup.get_template("
foo.txt"
另外,render_unicode()方法可以将模板的输出转换为一个Python的Unicode对象返回:
printmytemplate.render_unicode()
上面的方法调用未提供输出编码参数,你可以通过下列语法来进行编码:
printmytemplate.render_unicode().encode('
'
注意,Mako能将数据返回为任何encoding或unicode的能力暗示着,模板内部的输出流是一个Pythonunicode对象。
这种行为的详细描述在
TheUnicodeChapter.
6处理异常
模板异常可能在两种截然不同的地方出现。
第一种是当你查找,分析和编译模板时,另一种是当你运行模板的时候。
在模板的运行过程中,异常通常从产生问题的python代码出抛出。
Mako有其独立的一套异常类,它们大多数针对模板构造过程的查找和词法分析/编译阶段。
Mako还提供了一些库函数,这些函数用来帮助提供Mako相关的异常栈跟踪信息,并可用纯文本或HTML方式格式化异常信息。
不管是哪种情况,这些处理函数的作用在于将Python文件名,行号,以及代码例子转换为Mako的模板文件名,行号,以及代码范例。
在跟踪栈里对应于某个Moko模板的每一行,都回被转换为和源模板文件相关的。
为了格式化异常跟踪信息,系统提供了text_error_template和html_error_template函数。
它们都利用了sys.exc_info()函数来获取最近抛出的异常信息。
下面是常见的用法:
frommakoimportexceptions
try:
template=lookup.get_template(uri)
printtemplate.render()
except:
printexceptions.text_error_template().render()
如果使用HTML的输出函数:
printexceptions.html_error_template().render()
HTML输出函数也内建到了Template中。
通过format_exceptions这个标志位参数。
这样,任何在template的render阶段引发的异常,都会使得template的输出内容被html_error_template方法的输出所替代。
template=Template(filename="
/foo/bar"
format_exceptions=True)
printtemplate.render()
注意,上述模板的编译阶段发生在你构造Template对象本身的时候,并且没有定义输出流。
所以,在查找/解析/编译阶段引发的异常不会被处理,而是像平常那样被继续抛出到更高层次的调用堆栈上(繁殖,propagate)。
虽然pre-rendertraceback不会包含任何Mako特定的行,这意味着发生在rendering之前的异常,以及rendering过程中发生的异常,需要用不同的办法分别处理。
因此,上面的try/except模式可能是比较通用的一种写法。
被错误模板函数使用的内部对象是RichTraceback.该对象也可以被直接用于提供自定义错误视图。
下面是一个范例应用,可以描述其一般使用的API:
frommako.exceptionsimportRichTraceback
traceback=RichTraceback()
for(filename,lineno,function,line)intraceback.traceback:
print"
File%s,line%s,in%s"
%(filename,lineno,function)
printline,"
\n"
%s:
%s"
%(str(traceback.error.__class__.__name__),traceback.error)
关于
RichTraceback
的更深入信息可以查阅mako.exceptions的模块级文档。
二、语法
Mako模板是从文本流中进行解析的,流中可以包含任意内容:
XML,HTML,email文本,等等。
模板中可以包含Mako特定的指令(directives),可用于表示变量或表达式替换,控制结构(如条件和循环),服务器端注释,整段的Python代码,以及各种用于提供附加功能的标签(tags)。
所有这些将被编译为真实的Python代码。
这意味着你可以在Mako模板中利用Python几乎所有的强大特性。
1表达式替换
最简单的表达式是变量替换。
其语法是${},受Perl,Genshi,JSPEL和其他一些语言的启发:
thisisx:
${x}
以上代码中,x的字符串表示形式将被应用到模板的输出流中。
x的值通常来源于你提供给模板rendering函数作为参数的Context变量。
如果x的值未指定给模板,并且也未指定为局部变量,则会估算为一个特殊的值UNDEFINED.
${}中的内容会被Python直接估算,所以各种表达式都是支持的:
pythagoreantheorem:
${pow(x,2)+pow(y,2)}
在render到输出流之前,表达式的结果总是被估算为一个字符串。
2表达式转义(escaping)
Mako包含了一系列内建的转义机制,包括HTML,URI和XML转义,以及"
trim"
函数。
转义的动作可以通过|运算符附加到表达式后面:
${"
thisissometext"
|u}
上例中对表达式进行了URL转义,其结果是:
this+is+some+text.其中u代表URL转义,与之类似的,h代表HTML转义,x代表XML转义,而trim则是通常的trim函数。
可以在
FilteringandBuffering
中获取更多关于过滤器函数的内容,包括如何创建你自己的过滤器。
3控制结构
控制结构指的是控制程序流程的那些语法—条件(如if/else),循环(如while和for),以及try/except之类。
在Mako中,控制结构用%后附加常规Python控制结构的写法,并用另一个%语法"
end<
name>
结束语句块。
其中"
是该表达式的关键字:
%ifx==5:
thisissomeoutput
%endif
%可以出现在一行里的任何位置,只要其前面没有其他文本;
缩进是无所谓的。
Python中的所有“冒号”表达式在这里都完全支持,包括if/elif/else,while,for甚至def,尽管Mako有其内建的功能更强大的def标签。
%forain['
one'
two'
three'
four'
five'
]:
%ifa[0]=='
t'
:
itstwoorthree
%elifa[0]=='
f'
four/five
%else:
one
%endif
%endfor
4注释
注释有两种形式。
单行注释在一行中以##开头(前面可以有空白):
##这是一个注释.
...text...
而多行注释则使用<
%doc>
...文本..<
/%doc>
的语法:
这里是注释
更多注释
注意,这是Mako0.1.3的新特性。
在此之前的版本中,注释的语法是单个#符号,而这和CSS的元素指示语法冲突,并且不能很好的处理多行注释。
5换行过滤器(NewlineFilters)
反斜线("
\"
)字符放在任意一行的后面,会吃掉一个换行符。
hereisalinethatgoesonto\
anotherline.
上述语法会产生下列文本:
hereisalinethatgoesontoanotherline.
6Python语句块
任意python语句块都可以用<
%%>
标签来定义:
thisisatemplate
%
x=db.get_resource('
foo'
y=[z.elementforzinxifx.frobnizzle==5]
%>
%foreleminy:
element:
${y}
在<
内定义的python代码,其整体的缩进量是不重要的,但是他们内部的语句之间必须有正确的缩进层次(因为这里没法使用end),Mako的编译器会调整python语句块的缩进层次与其周围的其他生成的Python代码相配合。
7模块级的语句块
的一个变体是<
%!
%>
,代表模块级别的代码块。
其中的代码会在模板的模块级别执行,而不是在模板的rendering函数中。
所以,这段代码不能访问模板的context,仅在模板被加载到内存时被执行(有可能是相对于每应用程序仅执行一次,或者多次,这取决于运行时环境)。
可以使用<
来定义模板的导入语句:
importmylib
importre
deffilter(text):
returnre.sub(r'
^@'
'
text)
在模板中,可以在任何位置,定义任意数目的<
语句块;
他们在编译产生的模块文件中出现的次序和定义时相同。
8标签
Mako还提供了标签。
所有标签的语法都一样,类似于XML标签,不同之处在于其标签名称必须以%开头。
标签的关闭可以用反斜杠的内联形式,或者独立的关闭标签:
%defname="
foo"
buffered="
True"
>
thisisadef
/%def>
每种标签都定义了一系列特定的属性。
有些属性是必须的。
并且,很多属性支持估算操作(evaluation),也就是说你可以在属性文本中嵌入一个表达式(用${}语法)。
/foo/bar/${myfile}.txt"
属性是否支持运行时的估算,取决于标签的类型,以及该标签是如何编译成模板的。
想知道某个标签的属性是否支持估算,最好的办法就是去试验它!
如果不合法,词法器会告诉你。
下面是所有标签的一个简单介绍:
1<
%page>
定义了当前模板的总体特性,包括缓存参数,以及模板被调用时期待的参数列表(非必须)。
%pageargs="
x,y,z='
default'
定义缓存特性:
%pagecached="
cache_type="
memory"
关于<
使用的细节在
The"
body()"
method
Caching
中有深入描述。
目前只有<
标签是模板唯一的,其他的会被胡略,这在将来的发布版本中也许会被改变,但现在请确认这一点。
2<
%include>
类似于其他模板语言的一个标签,%include接受一个文件名称作为参数,调用被引用文件的输出结果。
header.html"
helloworld
footer.html"
3<
%def>
%def标签用于定义包含一系列内容的一个Python函数,此函数在当前模板的其他某个地方被调用到:
myfunc(x)"
thisismyfunc,xis${x}
${myfunc(7)}
%def标签比Python的def要强大一些,因为Mako的编译器为%def提供了很多额外服务,比如可以导出defs为模板“方法”,自动传播当前的context(原文:
automaticpropigationofthecurrentContext),缓冲/过滤/缓存标志位,以及带有内容的def调用,这使得defs的包可以被以参数的形式,提供给其他的def调用(不像听起来那么困难)。
Defs
中了解%def的详细内容。
backtosectiontop
4<
%namespace>
%namespace是Mako中相对Python
里import语句的等价物。
它允许访问其他模板文件的所有rendering函数和元数据,纯文本的python模块,以及局部定义的函数“包”。
%namespacefile="
functions.html"
import="
*"
%namespace编译后产生的对象是mako.runtime.Namespace的一个实例,这是在模块中被用来引用模板特定的信息(如当前的URI,继承结构以及其他一些东西)的一个中心结构,名称空间的详细描述在
Namespaces
中。
5<
%inherit>
允许模板可以在继承链中安排其自身的位置。
这是其他很多模板语言都有的一个熟悉的概念。
%inheritfile="
base.html"
当使用%inherit标签时,首先,控制权被转交给继承树最顶层的父模板,由它来决定如何配合继承自它的子模板来处理其中的调用区域(callingareas)的内容。
Mako在这方面提供了很多灵活性,包括动态继承(dynamicinheritance),内容包装(contentwrapping),以及多态的方法调用(polymorphicmethodcalls).详见
Inheritance。
6<
%call>
call标签用于调用<
%defs%>
标签,可传递额外的内嵌内容。
详细描述在
Callinga
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Mako 模板系统 模板 系统