zoukankan      html  css  js  c++  java
  • 模板库Mako的语法

    Mako模板从一个包含各种类型的内容的文本流解析得到,包括XML、HTML、email文本等。模板还可以包含Mako指令,用来表示变量和表达式替换、控制结构、服务器端注释、整块Python代码,还有用来提供额外功能的各种标签。所有这些结构都被编译为实际的Python代码。这意味着你可以在Mako模板的每个方面都充分利用Python的强大能力。

    表达式替换

    最简单的表达式是变量替换。语法为 ${} ,这是从Perl、Genshi、JSP EL等得到的启发:

    this is x: ${x}
    

    上面的例子会把 x 的字符串表示输出到模板的输出流。 x 通常来自于传递给模板渲染函数的 Context 。如果没有传入x 给模板,并且也没有本地赋值,那么就等于一个特殊的值 UNDEFINED 。

    ${} 标签中的内容由Python直接计算,因此也可以使用完整的表达式:

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

    表达式的结果都会在输出到输出流之前转换为字符串形式。

    表达式转义

    Mako有一组内建的转义机制,包括HTML、URI和XML转义,还有空白截断函数。这些转义可以用 | 操作添加到表达式替换:

    ${"this is some text" | u}
    

    上面将URL转义应用到表达式上,生成 this+is+some+text 。 u 表示URL转义, h 表示HTML转义, x 表示XML转义, 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 ,不过对 def Mako有更好的内建标签。

    % 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
    

    % 符号也可以被转义,如果你想在行首使用百分比符号,可以用 %% 来转义:

    %% some text
    
        %% some more text
    

    循环上下文

    循环上下文提供 % for 结构中的循环的额外信息:

    <ul>
    % for a in ("one", "two", "three"):
        <li>Item ${loop.index}: ${a}</li>
    % endfor
    </ul>
    

    参考 The Loop Context 。

    注释

    有两种形式的注释。单行注释在行首使用 ## :

    ## this is a comment.
    ...text ...
    

    多行注释通过 <%doc> ...text... </%doc> :

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

    新行过滤器

    行末的  字符可以将下一行连接到当前行:

    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: ${elem}
    % endfor
    

    在 <% %> 里面,可以写普通的Python代码块。代码的整体缩进不受限制,Mako编译器会根据生成的Python代码进行调节。

    模块级的块

    <% %> 的一个变种是模块级的块,用 <%! %> 表示。标签中的代码在模板的模块级别执行,而不是在模板的渲染函数中。因此,这些代码不能访问模板的上下文,并且只能在模板加载到内存时执行(一般每个应用一次,取决于运行环境)。使用 <%! %> 标签来声明模板的导入和纯Python函数:

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

    可以在模板中的任何位置声明任意数量的 <%! %> 块。它们将按出现的顺序生成为一个单独的模块代码块,放在所有渲染调用之前。

    标签

    Mako提供的其他东西以标签的形式出现。所有标签使用相同的语法,和XML标签类似,但是在标签名之前加上了 %字符。标签结束方式和XML类似:

    <%include file="foo.txt"/>
    
    <%def name="foo" buffered="True">
        this is a def
    </%def>
    

    每个标签都有一组属性。有些属性是必需的。很多属性支持运算,这意味着你可以在属性文本中嵌入一个表达式(使用 ${} ):

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

    属性是否支持运行时运算取决于标签的类型和它编译到模板的方式。想知道能否添加表达式的最好方法就是试一下!词法分析器会告诉你是否有效。

    下面是全部的标签的一个快速总结:

    <%page>

    该标签定义了模板的一些通用特性,包括缓存参数和模板调用的参数的可选列表。

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

    也可以定义缓存特性:

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

    目前每个模板只有一个 <%page> 标签生效,其他的会被忽略。以后的版本中这会被改进,但是现在请确保你的模板中只用了一个 <%page> 标签,否则可能得不到你想要的结果。 <%page> 的用途参考 The body() Method 和 Caching 。

    <%include>

    这是和其他模板语言类似的一个标签, %include 接受一个文件参数,调用那个文件的渲染结果:

    <%include file="header.html"/>
    
        hello world
    
    <%include file="footer.html"/>
    

    它还接受 <%page> 标签的参数,应用到导入的模板上:

    <%include file="toolbar.html" args="current_section='members', username='ed'"/>
    

    <%def>

    %def 标签定义一个Python函数,函数可以在模板的其他位置调用。基本的思想很简单:

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

    %def 标签比Python的 def 强大得多,因为Mako提供了很多额外的功能,比如能够将函数作为模板的“方法”,自动传递当前的 Context ,使用缓冲/过滤/缓存标志,作为参数传递给其他的函数调用。 %def 的全部细节见 Defs and Blocks 。

    <%block>

    <%block> 标签和 %def 类似,但它会在根作用域立即执行,而且可以是匿名的:

    <%block filter="h">
        some <html> stuff.
    </%block>
    

    借鉴了Jinja2的块,有名字的块实现了一种很方便的继承方法:

    <html>
        <body>
        <%block name="header">
            <h2><%block name="title"/></h2>
        </%block>
        ${self.body()}
        </body>
    </html>
    

    块在 Using Blocks 中有介绍,还有 Inheritance 。

    <%namespace>

    Mako中的 %namespace 和Python的 import 语句等价。通过它可以访问其他模板的所有的渲染函数和metadata,Python模块,还有本地定义的函数“包”。

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

    %namespace 生成的底层对象是一个 mako.runtime.Namespace 实例。它是模板中的一个核心结构,用来引用模板的特定信息,比如当前的URI、继承结构和其他一些东西。名字空间见 Namespaces 。

    <%inherit>

    通过继承可以实现模板的继承链。它和其他模板语言的概念类似。

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

    当使用 %inherit 标签时,控制首先被传递到继承模板的顶层模板,由它来决定如何处理调用部分。Mako在这部分实现的非常灵活,包括动态继承、内容封装、多态方法调用。参考 Inheritance 。

    <%nsname:defname>

    可以通过 <%<namespacename>:<defname>> 来在一个名字空间中自定义一个标签。它的单标签和双标签形式分别对应行内表达式和 <%call> 标签。

    <%mynamespace:somedef param="some value">
        this is the body
    </%mynamespace:somedef>
    

    如何创建自定义标签,参考 Calling a Def with Embedded Content and/or Other Defs 。

    <%call>

    %call 标签是用户定义标签的传统形式,大致和上面的 <%namespacename:defname> 等价。该标签也参考 Calling a Def with Embedded Content and/or Other Defs 。

    <%doc>

    %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>
    

    从模板中提前返回

    有时你想在模板或 <%def> 方法的中间停止处理,只用当前得到的结果。可以在Python代码块中使用 return 语句来实现。

    % if not len(records):
        No records found.
        <% return %>
    % endif
    

    或:

    <%
        if not len(records):
            return
    %>
  • 相关阅读:
    流量控制-QoS
    网关冗余-HSRP
    EIGRP负载均衡
    NAT负载均衡
    VLAN是什么
    交换机宽带优化、端口聚合
    二层安全之MAC Flooding解析与解决方法
    弱安全协议探测工具-sslciphercheck
    OpenSSL 与 SSL 数字证书概念贴
    【Linux安全】查看是否存在特权用户以及是否存在空口令用户
  • 原文地址:https://www.cnblogs.com/zhaojianwei/p/4666651.html
Copyright © 2011-2022 走看看