文档章节

Pyhton---模板库Mako的用法

P
 Py_cc
发布于 2015/04/23 13:26
字数 2005
阅读 17
收藏 0

Mako是一个高性能的Python模板库,它的语法和API借鉴了很多其他的模板库,如Django、Jinja2等等。

基本用法

创建模板并渲染它的最基本的方法是使用 Template 类:


1
2
3
from  mako.template  import  Template
=  Template( 'hello world!' )
print  t.render()

传 给 Template 的文本参数被编译为一个Python模块。模块包含一个 render_body() 函数,它产生模板的输出。调用 render() 方法时,Mako建立了一个模板的运行环境,并调用 render_body() 函数,把输出保存到缓冲,返回它的字符串内容。
render_body() 函数中可以访问一个变量集。可以向 render() 方法发送额外的关键词参数来指定这些变量:


1
2
3
from  mako.template  import  Template
=  Template( 'hello, ${name}!' )
print  t.render(name = 'yeolar' )

render() 方法使Mako创建一个 Context 对象,它存储模板可以访问的所有变量和一个用来保存输出的缓冲。也可以自己创建 Context ,用 render_context() 方法使模板用它来渲染:


1
2
3
4
5
6
7
8
from  mako.template  import  Template
from  mako.runtime  import  Context
from  StringIO  import  StringIO
=  Template( 'hello, ${name}!' )
buf  =  StringIO()
=  Context(buf, name = 'yeolar' )
t.render_context(c)
print  buf.getValue()

使用文件模板

Template 也可以从文件加载模板,使用 filename 参数:


1
2
3
from  mako.template  import  Template
=  Template(filename = '/docs/tpl.txt' )
print  t.render()

为了提高性能,从文件加载的 Template 还可以在文件系统中将生成的模块缓存为一般的Python模块文件(.py文件),这通过添加 module_directory 参数实现:


1
2
3
from  mako.template  import  Template
=  Template(filename = '/docs/tpl.txt' , module_directory = '/tmp/mako_modules' )
print  t.render()

上面的代码渲染后,会创建一个/tmp/mako_modules/docs/tpl.txt.py文件,其中包含模块的源代码。下次同样参数的 Template 创建时,自动重用这个模块文件。

使用TemplateLookup

到现在的例子都是有关单个 Template 对象的用法。如果模板中的代码要定位其他模板资源,需要某种使用URI来找到它们的方法。这种需求是由 TemplateLookup 类来达到的。这个类通过传入一个模板查找目录的列表来构造,然后作为关键词参数传给 Template 对象:


1
2
3
4
from  mako.template  import  Template
from  mako.lookup  import  TemplateLookup
lookup  =  TemplateLookup(directories = [ '/docs' ])
=  Template( '<%include file="header.txt" /> hello word!' , lookup = lookup)

上面创建的模板中包含文件header.txt。为了查找header.txt,传了一个 TemplateLookup 对象给它。
通常,应用会以文本文件形式在文件系统上存储大部分或全部的模板。一个真正的应用会直接从 TemplateLookup 取得它的模板,使用 get_template() 方法,它接受需要的模板的URI作为参数:


1
2
3
4
5
6
from  mako.template  import  Template
from  mako.lookup  import  TemplateLookup
lookup  =  TemplateLookup(directories = [ '/docs' ], module_directory = '/tmp/mako_modules' )
def  serve_template(t_name,  * * kwargs):
     =  lookup.get_template(t_name)
     print  t.render( * * kwargs)

上 面的例子中我们创建了一个 TemplateLookup ,它从/docs目录中查找模板,并把所有的模块文件存储到/tmp/mako_modules目录中。通过将传入的URI附加到每个查找目录来定位模 板,如传递/etc/beans/info.txt,将查找文件/docs/etc/beans/info.txt,如果没找到将抛出 TopLevelNotFound 异常。
当定位到模板的时候,传给 get_template() 调用的URI也会作为 Template 的 uri 属性。 Template 使用这个URI来得到模块文件的名字,因此上面的例子中对/etc/beans/info.txt会创建模块文件/tmp/mako_modules /etc/beans/info.txt.py。

设置收集的大小

TemplateLookup 还满足将内存中缓存的模板总数设为一个固定的值。默认情况 TemplateLookup 大小是不限的。可以用 collection_size 参数指定一个固定值:


1
lookup  =  TemplateLookup(directories = [ '/docs' ], module_directory = '/tmp/mako_modules' , collection_size = 500 )

上面的 lookup 将模板加载到内存中的上限是500个。之后,它将使用LRU策略来清理替换模板。

设置文件系统检查

TemplateLookup 的另一个重要标志是 filesystem_checks 。默认为 True ,每次 get_template() 方法返回一个模板,会比较原始模板文件的修改时间和模板的最近加载时间,如果文件更新,就重新加载和编译模板。在生产系统中,将 filesystem_checks 设为 False 能获得一些性能的提升。

使用Unicode和编码

Template 和 TemplateLookup 可以设置 output_encoding 和 encoding_errors 参数来将输出编码为Python支持的编码格式:


1
2
3
4
5
from  mako.template  import  Template
from  mako.lookup  import  TemplateLookup
lookup  =  TemplateLookup(directories = [ '/docs' ], output_encoding = 'utf-8' , encoding_errors = 'replace' )
=  lookup.get_template( 'foo.txt' )
print  t.render()

使用Python 3时,如果设置了 output_encoding , render() 方法将返回一个 bytes 对象,否则返回 string 。
render_unicode() 方法返回模板输出为Python unicode 对象,Python 3为 string :


1
print  t.render_unicode()

上面的方法没有输出编码的参数,可以自行编码:


1
print  t.render_unicode().encode( 'utf-8' 'replace' )

注意Mako中模板的底层输出流是Python Unicode对象。

处理异常

模板异常可能发生在两个地方。一个是当你查找、解析和编译模板的时候,一个是运行模板的时候。模板运行中发生的异常会正常在产生问题的 Python代码处抛出。Mako有自己的一组异常类,它们主要用于模板构造的查找和编译阶段。Mako提供了一些库例程用来对异常栈提供Mako的信 息,并将异常输出为文本或HTML格式。Python文件名、行号和代码片段会被转换为Mako模板文件名、行号和代码片段。Mako模板模块的行会被转 换为原始的模板文件对应行。

text_error_template() 和 html_error_template() 函数用于格式化异常跟踪。它们使用 sys.exc_info() 来得到最近抛出的异常。这些处理器的用法像下面这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
from  mako  import  exceptions
try :
     =  lookup.get_template(uri)
     print  t.render()
except :
     print  exceptions.text_error_template().render()
或者渲染为HTML:
from  mako  import  exceptions
try :
     =  lookup.get_template(uri)
     print  t.render()
except :
     print  exceptions.html_error_template().render()

html_error_template() 模板接受两个选项:指定 full=False 只渲染HTML的一节,指定 css=False 关闭默认的样式表。如:

1
print  exceptions.html_error_template().render(full = False )

HTML渲染函数也可以用 format_exceptions 标志加到 Template 中。这种情况下,模板在渲染阶段的任何异常在输出中的结果都会替换为 html_error_template() 的输出:

1
2
=  Template(filename = '/foo/bar' , format_exceptions = True )
print  t.render()

注 意上面模板的编译阶段发生在构造 Template 时,没有定义输出流。因此查找、解析、编译阶段发生的异常正常情况下不会被处理,而是传播下去。渲染前的追溯不包括Mako形式的行,这意味着渲染前和渲 染中发生的异常会用不同的方式处理,因此 try/except 可能更常用。

错误模板函数使用的底层对象是 RichTraceback 对象。这个对象也可以直接用来提供自定义的错误视图。下面是一个用法的样例:

1
2
3
4
5
6
7
8
9
10
from  mako.exceptions  import  RichTraceback
try :
     =  lookup.get_template(uri)
     print  t.render()
except :
     traceback  =  RichTraceback()
     for  (filename, lineno, function, line)  in  traceback.traceback:
         print  'File %s, line %s, in %s'  %  (filename, lineno, function)
         print  line,  '\n'
     print  '%s: %s'  %  ( str (traceback.error.__class__.__name__), traceback.error)

集成Mako

在Django中集成Mako

通过Django的中间件可以集成Mako。首先需要安装django-mako模块。
在Django项目的settings.py文件中,修改 MIDDLEWARE_CLASSES ,添加 djangomako.middleware.MakoMiddleware 。使用 render_to_response() 函数即可使用:

1
2
3
from  djangomako.shortcuts  import  render_to_response
def  hello_view(request):
     return  render_to_response( 'hello.txt' , { 'name' 'yeolar' })

在Tornado中集成Mako

在Tornado中可以直接使用Mako,下面是一个使用示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
  
import  tornado.web
import  mako.lookup
import  mako.template
LOOK_UP  =  mako.lookup.TemplateLookup(
         directories = [TEMPLATE_PATH], module_directory = '/tmp/mako' ,
         output_encoding = 'utf-8' , encoding_errors = 'replace' )
class  BaseHandler(tornado.web.RequestHandler):
     def  initialize( self , lookup = LOOK_UP):
         '''Set template lookup object, Defalut is LOOK_UP'''
         self ._lookup  =  lookup
     def  render_string( self , filename,  * * kwargs):
         '''Override render_string to use mako template.
         Like tornado render_string method, this method
         also pass request handler environment to template engine.
         '''
         try :
             template  =  self ._lookup.get_template(filename)
             env_kwargs  =  dict (
                 handler  =  self ,
                 request  =  self .request,
                 current_user  =  self .current_user,
                 locale  =  self .locale,
                 =  self .locale.translate,
                 static_url  =  self .static_url,
                 xsrf_form_html  =  self .xsrf_form_html,
                 reverse_url  =  self .application.reverse_url,
                 )
             env_kwargs.update(kwargs)
             return  template.render( * * env_kwargs)
         except :
             # exception handler
             pass
     def  render( self , filename,  * * kwargs):
         self .finish( self .render_string(filename,  * * kwargs))


© 著作权归作者所有

P
粉丝 0
博文 15
码字总数 4633
作品 0
济南
私信 提问
Python模板库Mako的用法

Mako是一个高性能的Python模板库,它的语法和API借鉴了很多其他的模板库,如Django、Jinja2等等。 基本用法 创建模板并渲染它的最基本的方法是使用 Template 类: from mako.template impor...

北方攻城师
2014/07/14
3.7K
0
Python模板库Mako的用法

Mako是一个高性能的Python模板库,它的语法和API借鉴了很多其他的模板库,如Django、Jinja2等等。 基本用法 创建模板并渲染它的最基本的方法是使用 Template 类: 传给 Template 的文本参数被...

楠木楠
2016/09/15
473
0
用mako增强django模板,用法像jsp

用mako增强django模板 django默认的模板功能还可以,但是不能直接用python的语法,mako解决了这个痛点,使得django的模板变得像jsp一样,可以直接使用python的语法做一些事情。 makodjango-m...

duoduo3_69
2014/09/25
1K
5
3 个 Python 模板库比较

你的下一个 Python 项目需要一个模板引擎来自动生成 HTML 吗?这有几种选择。 在我的日常工作中,我花费大量的时间将各种来源的数据转化为可读的信息。虽然很多时候这只是电子表格或某种类型...

20%
2018/06/05
0
0
用django-pipeline为静态文件添加hash

用django-pipeline为静态文件添加hash 为什么需要hash静态文件? 请看大公司里怎样开发和部署前端代码? 张云龙的答案。 这样,当静态文件有修改时,会很方便的拿到最新的修改版本,而未修改...

duoduo3_69
2014/10/31
154
0

没有更多内容

加载失败,请刷新页面

加载更多

作为一个(IT)程序员!聊天没有话题?试试这十二种技巧

首先呢?我是一名程序员,经常性和同事没话题。 因为每天都会有自己的任务要做,程序员对于其他行业来说;是相对来说比较忙的。你会经常看到程序员在发呆、调试密密麻麻代码、红色报错发呆;...

小英子wep
今天
14
0
【SpringBoot】产生背景及简介

一、SpringBoot介绍 Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化新 Spring 应用的初始搭建以及开发过程,该框架使用了特定的方式来进行配置,从而使开发人员不再需要...

zw965
今天
5
0
简述并发编程分为三个核心问题:分工、同步、互斥。

总的来说,并发编程可以总结为三个核心问题:分工、同步、互斥。 所谓分工指的是如何高效地拆解任务并分配给线程,而同步指的是线程之间如何协作,互斥则是保证同一时刻只允许一个线程访问共...

dust8080
今天
6
0
OSChina 周四乱弹 —— 当你简历注水但还是找到了工作

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @花间小酌 :#今日歌曲推荐# 分享成龙的单曲《男儿当自强》。 《男儿当自强》- 成龙 手机党少年们想听歌,请使劲儿戳(这里) @hxg2016 :刚在...

小小编辑
今天
3.3K
22
靠写代码赚钱的一些门路

作者 @mezod 译者 @josephchang10 如今,通过自己的代码去赚钱变得越来越简单,不过对很多人来说依然还是很难,因为他们不知道有哪些门路。 今天给大家分享一个精彩的 GitHub 库,这个库整理...

高级农民工
昨天
10
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部