Mako 模板系统文档翻译(2) 语法

翻译:木野狐 http://rchen.cnblogs.com/
原文:http://www.makotemplates.org/docs/syntax.html
译文:

Version: 0.1.5 Last Updated: 05/01/07 20:21:35

语法

Mako 模板是从文本流中进行解析的,流中可以包含任意内容: XML, HTML, email 文本,等等。模板中可以包含 Mako 特定的指令(directives),可用于表示变量或表达式替换,控制结构(如条件和循环),服务器端注释,整段的 Python 代码,以及各种用于提供附加功能的标签(tags)。所有这些将被编译为真实的 Python 代码。这意味着你可以在 Mako 模板中利用 Python 几乎所有的强大特性。

表达式替换

最简单的表达式是变量替换。其语法是 ${},受 Perl, Genshi, JSP EL 和其他一些语言的启发:

this is x: ${x}

以上代码中,x 的字符串表示形式将被应用到模板的输出流中。x 的值通常来源于你提供给模板 rendering 函数作为参数的 Context 变量。如果 x 的值未指定给模板,并且也未指定为局部变量,则会估算为一个特殊的值 UNDEFINED.

${} 中的内容会被 Python 直接估算,所以各种表达式都是支持的:

pythagorean theorem:  ${pow(x,2) + pow(y,2)}

在 render 到输出流之前,表达式的结果总是被估算为一个字符串。

表达式转义(escaping)

Mako 包含了一系列内建的转义机制,包括 HTML, URI 和 XML 转义,以及 "trim" 函数。转义的动作可以通过 | 运算符附加到表达式后面:

${"this is some text" | u}

上例中对表达式进行了 URL 转义,其结果是:this+is+some+text. 其中 u 代表 URL 转义,与之类似的,h 代表 HTML 转义,x 代表 XML 转义,而 trim 则是通常的 trim 函数。

可以在 Filtering and Buffering 中获取更多关于过滤器函数的内容,包括如何创建你自己的过滤器。

控制结构

控制结构指的是控制程序流程的那些语法 — 条件(如 if/else),循环(如 while 和 for),以及 try/except 之类。
在 Mako 中,控制结构用 % 后附加常规 Python 控制结构的写法,并用另一个 % 语法 "end<name>" 结束语句块。其中 "<name>" 是该表达式的关键字:

% if x==5:
    this is some output
% endif

% 可以出现在一行里的任何位置,只要其前面没有其他文本;缩进是无所谓的。Python 中的所有“冒号”表达式在这里都完全支持,包括 if/elif/else, while, for 甚至 def,尽管 Mako 有其内建的功能更强大的 def 标签。

% for a in ['one', 'two', 'three', 'four', 'five']:
    % if a[0] == 't':
     its two or three
    % elif a[0] == 'f':
    four/five
    % else:
    one
    %endif
% endfor

注释

注释有两种形式。单行注释在一行中以 ## 开头(前面可以有空白):

## 这是一个注释.
...text ...

而多行注释则使用<%doc> ... 文本.. </%doc> 的语法:

<%doc>
    这里是注释
    更多注释
</%doc>

注意,这是 Mako 0.1.3 的新特性。在此之前的版本中,注释的语法是单个 # 符号,而这和 CSS 的元素指示语法冲突,并且不能很好的处理多行注释。

换行过滤器(Newline Filters)

反斜线 ("\") 字符放在任意一行的后面,会吃掉一个换行符。

here is a line that goes onto \
another line.

上述语法会产生下列文本:

here is a line that goes onto another line.

Python 语句块

任意 python 语句块都可以用 <% %> 标签来定义:

this is a template
<%
    x = db.get_resource('foo')
    y = [z.element for z in x if x.frobnizzle==5]
%>
% for elem in y:
    element: ${y}
% endfor

在 <% %> 内定义的 python 代码,其整体的缩进量是不重要的,但是他们内部的语句之间必须有正确的缩进层次(因为这里没法使用 end),Mako 的编译器会调整 python 语句块的缩进层次与其周围的其他生成的 Python 代码相配合。

模块级的语句块

<% %> 的一个变体是 <%! %>,代表模块级别的代码块。其中的代码会在模板的模块级别执行,而不是在模板的 rendering 函数中。所以,这段代码不能访问模板的 context,仅在模板被加载到内存时被执行(有可能是相对于每应用程序仅执行一次,或者多次,这取决于运行时环境)。可以使用 <%! %> 来定义模板的导入语句:

<%!
    import mylib
    import re

    def filter(text):
        return re.sub(r'^@', '', text)
%>

在模板中,可以在任何位置,定义任意数目的 <%! %> 语句块;他们在编译产生的模块文件中出现的次序和定义时相同。

标签

Mako 还提供了标签。所有标签的语法都一样,类似于 XML 标签,不同之处在于其标签名称必须以 % 开头。标签的关闭可以用反斜杠的内联形式,或者独立的关闭标签:

<%include file="foo.txt"/>

<%def name="foo" buffered="True">
    this is a def
</%def>

每种标签都定义了一系列特定的属性。有些属性是必须的。并且,很多属性支持估算操作(evaluation),也就是说你可以在属性文本中嵌入一个表达式(用 ${} 语法)。

<%include file="/foo/bar/${myfile}.txt"/>

属性是否支持运行时的估算,取决于标签的类型,以及该标签是如何编译成模板的。想知道某个标签的属性是否支持估算,最好的办法就是去试验它!如果不合法,词法器会告诉你。

下面是所有标签的一个简单介绍:

<%page>


定义了当前模板的总体特性,包括缓存参数,以及模板被调用时期待的参数列表(非必须)。

<%page args="x, y, z='default'"/>

定义缓存特性:

<%page cached="True" cache_type="memory"/>

关于 <%page> 使用的细节在 The "body()" method 和 Caching 中有深入描述。
目前只有 <%page> 标签是模板唯一的,其他的会被胡略,这在将来的发布版本中也许会被改变,但现在请确认这一点。

<%include>

类似于其他模板语言的一个标签,%include 接受一个文件名称作为参数,调用被引用文件的输出结果。

<%include file="header.html"/>

    hello world

<%include file="footer.html"/>

<%def>

%def 标签用于定义包含一系列内容的一个 Python 函数,此函数在当前模板的其他某个地方被调用到:

<%def name="myfunc(x)">
    this is myfunc, x is ${x}
</%def>

${myfunc(7)}

%def 标签比 Python 的 def 要强大一些,因为 Mako 的编译器为 %def 提供了很多额外服务,比如可以导出 defs 为模板“方法”,自动传播当前的 context (原文:automatic propigation of the current Context),缓冲/过滤/缓存 标志位,以及带有内容的 def 调用,这使得 defs 的包可以被以参数的形式,提供给其他的 def 调用(不像听起来那么困难)。可以在 Defs 中了解 %def 的详细内容。

back to section top

<%namespace>

%namespace 是 Mako 中相对 Python 里 import 语句的等价物。它允许访问其他模板文件的所有 rendering 函数和元数据,纯文本的 python 模块,以及局部定义的函数“包”。

<%namespace file="functions.html" import="*"/>

%namespace 编译后产生的对象是 mako.runtime.Namespace 的一个实例,这是在模块中被用来引用模板特定的信息(如当前的 URI,继承结构以及其他一些东西)的一个中心结构,名称空间的详细描述在 Namespaces 中。

<%inherit>

允许模板可以在继承链中安排其自身的位置。这是其他很多模板语言都有的一个熟悉的概念。

<%inherit file="base.html"/>

当使用 %inherit 标签时,首先,控制权被转交给继承树最顶层的父模板,由它来决定如何配合继承自它的子模板来处理其中的调用区域(calling areas)的内容。Mako 在这方面提供了很多灵活性,包括动态继承(dynamic inheritance), 内容包装(content wrapping), 以及多态的方法调用(polymorphic method calls). 详见 Inheritance

<%call>

call 标签用于调用 <%defs %> 标签,可传递额外的内嵌内容。详细描述在 Calling a def with embedded content and/or other defs.

<%doc>

处理多行注释:

<%doc>
    these are comments
    more comments
</%doc>

## 用于处理单行注释。

<%text>

该标签使得 Mako 的词法器对模板指令的常规解析动作停止,并以纯文本的形式返回其整个内容部分。该语法可以用来书写 Mako 的文档:

<%text filter="h">
    heres some fake mako ${syntax}
    <%def name="x()">${x}</%def>
</%text>
 
 
上一节: 使用基础 | 下一节: 函数定义 

 

posted on 2007-06-15 11:33  NeilChen  阅读(6387)  评论(2编辑  收藏  举报

导航