简介
Mako 是一个 Python 模板程序. 用于给定一个字符串, 或给定一个文件, 使用 Python 对象值动态地替换其中的一部分内容.可是使用 pip 或 easy_install 安装 Mako 库.
# pip install Mako
# easy_install Mako
使用
基本文本替换
安装完成后, 在交互环境中可以通过下面的代码来测试 Mako>>> import mako.template
>>> print mako.template.Template('Hello, ${ what }!').render(what='Mako')
Hello, Mako!
Hello, ${ what }!
中的动态内容进行替换. 动态内容是形如 ${ what }
这样的 Mako 标记, 它表示将传递给 render
函数的字典中, what
对应的项的值替换这个标记. 因此上面的 render
结果便是 Hello, Mako!
.替换文件中的动态内容
更多的应用场景是将需要生成的内容写成一个文件模板 (如 HTML 页面), 读取这个页面并生成结果内容. 在当前目录下创建 hello-mako.html 文件, 内容如下<html>
<body>
Dear ${ username }, welcome back!
import mako.template
templ = mako.template.Template(filename='hello-mako.html')
print templ.render(username='Mako')
使用中文及指定编码
上面的页面模板代码中如果包含中文或其它非 ASCII 字符, 如<html>
<body>
你好, ${ username }, 欢迎回来!
mako.template.Template
对象时多半会挂掉. 要为 Mako 模板指定输入编码方式才行import mako.template
templ = mako.template.Template(filename='hello-mako.html', input_encoding='utf-8')
print templ.render(username=u'柑奈')
分支
接下来, 如果这个用户是个管理员用户, 那么希望为这个用户呈现一个后台管理的入口 (当然其它用户就没这个福利了), 那么可以用 Mako 提供的分支来实现你好, ${ username }, 欢迎回来!
%if is_admin:
<a href='/admin'>管理页面</a>
%endif
templ = mako.template.Template(filename='hello-mako.html', input_encoding='utf-8')
print templ.render(username=u'柑奈', is_admin=False)
print templ.render(username=u'柑奈', is_admin=True)
%if
%endif
之间表示一段分支. 如果确实需要书写一个百分号, 而不是作为 Mako 的指令符号, 那么此处须连续两个百分号 %%
来转义, 通常页面上似乎也不会出现那么多百分号, 所以这个应该还是可以接受的吧.关于分支, 更详细的例子是
%if condition_a:
do_a
%elif condition_b:
do_b
%else:
do_c
%endif
对象式引用
上面的例子中出现了两个模板参数username
跟 is_admin
. 当然这两个参数可能同为一个 user
对象的两枚属性, 因此, 实际上可以向模板传递一个参数 user
, 而 username
与 is_admin
以其属性形式给出. 如此的话, 上面的页面模板可以改成<html>
<body>
Dear ${ user.username }, welcome back!
%if user.is_admin:
<a href='/admin'>Admin</a>
%endif
class User:
def __init__(self, username, is_admin):
self.username = username
self.is_admin = is_admin
templ = mako.template.Template(filename='hello-mako.html', input_encoding='utf-8')
print templ.render(user=User(u'柑奈', False))
循环
如果该用户登入之后, 需要一个列表来显示该用户最近收到的消息, 这些消息也可以作为模板参数注入到页面中, 不过注入的不是一个对象, 而是一个列表的对象, 假定这些消息有 id, title 等属性, 那么Dear ${ user.username }, welcome back!
%if user.is_admin:
<a href='/admin'>Admin</a>
%endif
<ul>
%for m in messages:
<li><a href='/msg?id=${m.id}'>${m.title}</a></li>
%endfor
</ul>
%for 每次迭代的对象 in 列表参数:
循环输出的内容
%endfor
class Message:
def __init__(self, id, title):
self.id = id
self.title = title
templ = mako.template.Template(filename='hello-mako.html', input_encoding='utf-8')
print templ.render(user=User(u'柑奈', False),
messages=[Message(0, 'Abc'), Message(1, 'Def')])
HTML 字符串转义
当然上面有安全隐患, 比如某个用户发了个消息, 标题是一段恶意 HTML 代码, 那么收信用户登录上来就被 XSS 了. 这时就要用到 HTML 转义. 在 Mako 里可以使用下面的语法来 HTML 转义<li><a href='/msg?id=${m.id}'>${m.title | h}</a></li>
${m.id | u}
.这里仅列举 Mako 的常见功能. 更详细的请参阅 Mako 模板语法手册.