• Templetor: web.py 模板系统
  • Introduction
  • 使用模板系统
  • 语法
    • 表达式用法
    • 赋值
    • 过滤
    • 新起一行用法
    • 转义 $
    • 注释
    • 控制结构
    • 其他
      • 使用 def
      • 代码
      • 使用 var
  • 内置 和 全局
  • 安全
  • 从 web.py 0.2 升级

    Templetor: web.py 模板系统

    Introduction

    web.py 的模板语言叫做 Templetor,它能负责将 python 的强大功能传递给模板系统。在模板中没有重新设计语法,它是类 python 的。 如果你会 python,你可以顺手拈来。

    这是一个模板示例:

    1. $def with (name)
    2. Hello $name!

    第一行表示模板定义了一个变量 name。第二行中的 $name 将会用 name 的值来替换。

    如果是从 web.py 0.2 升级请看这里 升级 部分。

    使用模板系统

    通用渲染模板的方法:

    1. render = web.template.render('templates')
    2. return render.hello('world')

    render 方法从模板根目录查找模板文件,render.hello(..)表示渲染 hello.html 模板。实际上,系统会在根目录去查找叫 hello的所有文件,直到找到匹配的。(事实上他只支持 .html 和 .xml 两种)

    除了上面的使用方式,你也可以直接用文件的方式来处理模板 frender

    1. hello = web.template.frender('templates/hello.html')
    2. render hello('world')

    直接使用字符串方式:

    1. template = "$def with (name)\nHello $name"
    2. hello = web.template.Template(template)
    3. return hello('world')

    语法

    表达式用法

    特殊字符 $ 被用于特殊的 python 表达式。表达式能够被用于一些确定的组合当中 (){}:

    1. Look, a $string.
    2. Hark, an ${arbitrary + expression}.
    3. Gawk, a $dictionary[key].function('argument').
    4. Cool, a $(limit)ing.

    赋值

    有时你可能需要定义一个新变量或给一些变量重新赋值,如下:

    1. $ bug = get_bug(id)
    2. <h1>$bug.title</h1>
    3. <div>
    4. $bug.description
    5. <div>

    注意 $在赋值变量名称之前要有一个空格,这有区别于常规的赋值用法。

    过滤

    模板默认会使用 web.websafe 过滤 html 内容(encodeing 处理)。

    1. >>> render.hello("1 < 2")
    2. "Hello 1 &lt; 2"

    不需要过滤可以在 $ 之后 使用 :。示例:

    1. Html 内容不会被义
    2. $:form.render()

    新起一行用法

    在行末添加 \ 代表显示层该内容不会被真实处理成一行。

    1. If you put a backslash \
    2. at the end of a line \
    3. (like these) \
    4. then there will be no newline.

    转义 $

    使用 $$ 可以在输出的时候显示字符 $.

    1. Can you lend me $$50?

    注释

    $# 是注释指示符。任何以 $# 开始的某行内容都被当做注释。

    1. $# this is a comment
    2. Hello $name.title()! $# display the name in title case

    控制结构

    模板系统支持 for, while, if, elifelse。像 python 一样,这里是需要缩进的。

    1. $for i in range(10):
    2. I like $i
    3. $for i in range(10): I like $i
    4. $while a:
    5. hello $a.pop()
    6. $if times > max:
    7. Stop! In the name of love.
    8. $else:
    9. Keep on, you can do it.

    for 循环内的成员变量只在循环内发生可用:

    1. loop.index: the iteration of the loop (1-indexed)
    2. loop.index0: the iteration of the loop (0-indexed)
    3. loop.first: True if first iteration
    4. loop.last: True if last iteration
    5. loop.odd: True if an odd iteration
    6. loop.even: True if an even iteration
    7. loop.parity: "odd" or "even" depending on which is true
    8. loop.parent: the loop above this in nested loops

    有时候,他们使用起来很方便:

    1. <table>
    2. $for c in ["a", "b", "c", "d"]:
    3. <tr class="$loop.parity">
    4. <td>$loop.index</td>
    5. <td>$c</td>
    6. </tr>
    7. </table>

    其他

    使用 def

    可以使用 $def 定义一个新的模板函数,支持使用参数。

    1. $def say_hello(name='world'):
    2. Hello $name!
    3. $say_hello('web.py')
    4. $say_hello()

    其他示例:

    1. $def tr(values):
    2. <tr>
    3. $for v in values:
    4. <td>$v</td>
    5. </tr>
    6. $def table(rows):
    7. <table>
    8. $for row in rows:
    9. $:row
    10. </table>
    11. $ data = [['a', 'b', 'c'], [1, 2, 3], [2, 4, 6], [3, 6, 9] ]
    12. $:table([tr(d) for d in data])

    代码

    可以在 code 块书写任何 python 代码:

    1. $code:
    2. x = "you can write any python code here"
    3. y = x.title()
    4. z = len(x + y)
    5. def limit(s, width=10):
    6. """limits a string to the given width"""
    7. if len(s) >= width:
    8. return s[:width] + "..."
    9. else:
    10. return s
    11. And we are back to template.
    12. The variables defined in the code block can be used here.
    13. For example, $limit(x)

    使用 var

    var 块可以用来定义模板结果的额外属性:

    1. $def with (title, body)
    2. $var title: $title
    3. $var content_type: text/html
    4. <div id="body">
    5. $body
    6. </div>

    以上模板内容的输出结果如下:

    1. >>> out = render.page('hello', 'hello world')
    2. >>> out.title
    3. u'hello'
    4. >>> out.content_type
    5. u'text/html'
    6. >>> str(out)
    7. '\n\n<div>\nhello world\n</div>\n'

    内置 和 全局

    像 python 的任何函数一样,模板系统同样可以使用内置以及局部参数。很多内置的公共方法像 rangeminmax等,以及布尔值 TrueFalse,在模板中都是可用的。部分内置和全局对象也可以使用在模板中。

    全局对象可以使用参数方式传给模板,使用 web.template.render

    1. import web
    2. import markdown
    3. globals = {'markdown': markdown.markdown}
    4. render = web.template.render('templates', globals=globals)

    内置方法是否可以在模板中也是可以被控制的:

    1. # 禁用所有内置方法
    2. render = web.template.render('templates', builtins={})

    安全

    模板的设计想法之一是允许非高级用户来写模板,如果要使模板更安全,可在模板中禁用以下方法:

    • 不安全部分像 importexec 等;
    • 允许属性开始部分使用 _
    • 不安全的内置方法 open, getattr, setattr 等。如果模板中使用以上提及的会引发异常 SecurityException

    从 web.py 0.2 升级

    新版本大部分兼容早期版本,但仍有部分使用方法会无法运行,看看以下原因:

    • Template output is always storage like TemplateResult object, however converting it to unicode or str gives the result as unicode/string.
    • 重定义全局变量将无法正常运行,如果 x 是全局变量下面的写法是无法运行的。
    1. $ x = x + 1

    以下写法仍被支持,但不被推荐。

    • 如果你原来用 \$ 反转美元字符串, 推荐用 $$ 替换;
    • 如果你有时会修改 web.template.Template.globals,建议通过向 web.template.render 传变量方式来替换。