ZPT参考手册


            
            
            
        
            
               
1. TAL概述
模板属性语言(TAL)标准是一种属性语言,用于创建动态模板。它可以实现文档元素的替换、重复或忽略。
TAL中的语句是XML属性。这些属性可以在XMl或HTML中使用,从而实现页面模板的功能。
TAL语句由属性和数值组成。例如,content语句可以这样:
tal:content="string:Hello"
大多数的语句需要表达式,但表达式句法并不属于TAL,而是属于TALES。
1.1. TAL 名称空间
TAL名称空间URI定义为:
xmlns:tal="http://xml.zope.org/namespaces/tal"
当在Zope中创建模板时,不需要用内容类型text/html声明XML名称空间,对于其它内容类型时才需要声明。
1.2. TAL 语句
TAL语句包括:
  • tal:attributes - 动态更改元素属性。
    • tal:define - 定义变量。
    • tal:condition - 测试条件。
    • tal:content - 替换元素中的内容。
    • tal:omit-tag - 忽略一个元素,保留元素内容。
    • tal:on-error - 处理错误。
    • tal:repeat - 重复一个元素。
    • tal:replace - 替换元素的内容,删除元素,保留内容。

    语句中的表达式可以返回任何类型的数值,大多数语句只使用字符型数据。表达式语言必须定义一个名为nothing的数值,它不是字符串。这个数值适用于删除元素或属性。
    1.3. 执行顺序
    如果每个元素中只有一个TAL语句,执行的顺序很简单。从根元素开始,顺序执行每个元素语句。
    在同一元素中可以结合多个语句。但content和replace不能一起使用。
    由于TAL把语句看作是XML属性,即使在HTML文档中,不能按照编写的顺序来决定执行的顺序。因此需要对执行的顺序进行规定。
    当一个元素中含有多个语句时,按照以下顺序执行:
    • define
    • condition
    • repeat
    • content or replace
    • attributes
    • omit-tag
      由于on-error语句只有发生错误时才用到,因此没有在此列出来。
      按照这样的顺序执行,原因是:由于其它语句会用到变量,因此define先执行。接下来需要判断是否需要使用当前的元素,因此接下来是
      condition;另外condition依赖于刚才定义的变量,所以define后边是condition。由于通过循环的方式用不同值替换某些元素
      更具有价值,因此接下来是repeat。由于替换属性没有更多的意义,因此放在后边。
      1.4. 参见
      TALES 概述
      METAL 概述
      tal:attributes
      tal:define
      tal:condition
      tal:content
      tal:omit-tag
      tal:on-error
      tal:repeat
      tal:replace
      2. attributes: 替换元素属性
      2.1. 句法
      tal:attributes 句法:
      argument             ::= attribute_statement [';' attribute_statement]*
      attribute_statement  ::= attribute_name expression
      attribute_name       ::= [namespace-prefix ':'] Name
      namespace-prefix     ::= Name
    • 注意:如果你想在表达式中包含分号(;),必须通过使用两个符号(;;)来使用。

    2.2. 描述
    tal:attributes语句用一个动态数值替换(或创建一个属性)属性值。如果你通过多个名称空间生成XML文档,需要在属性中加上名称空间前缀,比如 html:table。如果需要 的话,每个表达式的值会转换成字符串。
    如果表达式结果为nothing,那么就从语句元素中删除。如果表达式结果为默认值,则属性保持不变。每个属性是独立的,因此可以在同一语句中处理多个属性。
    如果在一个元素中使用了tal:attributes语句,还使用了tal:replace,则tal:attributes将忽略。
    如果同时使用了tal:attributes和tal:repeat语句,每次循环都进行属性替换。
    2.3. 例子
    替换一个链接:
    替换两个属性:
    3. condition: 根据条件插入或删除元素
    3.1. 句法
    tal:condition 句法:
    argument ::= expression
    3.2. 描述
    根据tal:condition语句,如果符合条件,则在模板中插入元素,否则忽略。如果它的表达式求值为真,则继续处理元素,否则立即从模板中删除。nothing为假,default等同于返回真。
    注意:Zope认为缺少变量,None,0,空字符串和空序列为假,其它的值为真。
    3.3. 例子
    在插入变量前先测试(第一个例子测试是否存在并求值,第二个例子只测试是否存在):
    message goes here
    message goes here
    测试多个条件:
         Even
         Odd
    4. content: 替换元素内容
    4.1. 句法
    tal:content 句法:
    argument ::= (['text'] | 'structure') expression
    4.2. 描述
    不是替换整个元素,而是在元素内容部分用tal:content替换,插入文本或结构(structure)。这个语句的参数和tal:replace相同。如果表达式结果为nothing,内容部分为空。如果表达式结果为默认值,则内容部分保持不变。
    默认的替换方式是文本替换。通过使用structure关键字,可以保持文本不变,即可以插入HTML/XML标记符。
    4.3. 例子
    插入用户名称:
    Fred Farkas
    插入HTML/XML:
    marked up
       content goes here.
    4.4. 参见
    tal:replace
    5. define: 定义变量
    5.1. 句法
    tal:define 句法:
    argument       ::= define_scope [';' define_scope]*
    define_scope   ::= (['local'] | 'global') define_var
    define_var     ::= variable_name expression
    variable_name  ::= Name
    • 注意:如果你想在表达式中包含分号(;),必须使用两个分号(;;)。

    5.2. 描述
    tal:define用于定义变量。你可以定义两种类型的TAL变量:本地变量和全局变量。当你在一个元素中定义了一个本地变量,则只能在那个元素
    和所包含的元素中使用。如果在所包含的元素中重新定义本地变量,那么新的定义替换原来的定义。当你定义了一个全局变量,就可以在定义以后在任何位置使用变
    量。如果你重新定义了全局变量,从重新定义的位置开始有效。
    注意:默认为本地变量。
    如果表达式求值结果为nothing,那么变量的值为nothing。如果求值结果为默认值,则变量的值为默认值。
    5.3. 例子
    定义一个全局变量:
    tal:define="global company_name string:Zope Corp, Inc."
    定义两个变量,第二个变量依赖于第一个:
    tal:define="mytitle template/title; tlen python:len(mytitle)"
    6. omit-tag: 删除元素,保留内容
    6.1. 句法
    tal:omit-tag 句法:
    argument ::= [ expression ]
    6.2. 描述
    tal:omit-tag语句保留元素中的内容,同时删除起始和结尾部分的标记符。
    如果表达式求值结果为假,则继续处理,标记符不删除。如果表达式求值结果为真,或没有提供表达式,则替换元素中的内容。
    Zope认为空字符串、空序列、0、None和nothing为假,其它值为真,包括默认值。
    6.3. 例子
    无条件忽略一个标记符:
      ...but this text will remain.
    有条件忽略一个标记符:
    I may be bold.
    上边的例子中,如果变量bold为假,则忽略b标记符。
    创建10个p标记符,没有合拢标记符:
      1
    7. on-error: 处理错误
    7.1. 句法
    tal:on-error 句法:
    argument ::= (['text'] | 'structure') expression
    7.2. 描述
    tal:on-error语句用于处理错误。当一个TAL语句产生错误时,会搜索tal:on-error语句,调用第一个找到的tal:on-error。使用方法如同tal:content。
    本地变量error有三个属性:
    type 异常的类型 value 异常实例 traceback 回溯对象
    常见的错误是文字错误或表达式为nothing。更复杂一点的处理错误的方式是调用一个脚本。
    7.3. 例子
    显示简单的错误消息:
    Ishmael
    删除元素:
    Ishmael
    调用一个脚本:
      ...
    处理错误的脚本可以这样:
    ## Script (Python) "errHandler"
    ##bind namespace=_
    ##
    error=_['error']
    if error.type==ZeroDivisionError:
        return "Can't divide by zero."
    else
        return """An error ocurred.
                  Error type: %s
                  Error value: %s""" % (error.type,
                                               error.value)
    注意 这里的 namespace=_ 可在Script(Python)对象的Bingings标签页面中设置。 namespace表示调用方提供的名字空间。
    7.4. 参见
    Python Tutorial: Errors and Exceptions
    Python Built-in Exceptions
    8. repeat: 重复元素
    8.1. 句法
    tal:repeat 句法:
    argument      ::= variable_name expression
    variable_name ::= Name
    8.2. 描述
    tal:repeat语句根据序列中的每个数据项重复处理元素。表达式求值结果应该为一个序列。如果序列为空,那么这个语句所在的元素被删除,否则重复处理序列中的每一项。如果表达式为默认值,那么不发生改变,并且没有新定义的变量。
    8.3. 循环变量
    使用循环变量可访问当前循环相关信息,比如循环的序号。循环变量和本地变量一样,但是只能通过内建的变量repeat来调用。
    循环变量包括以下信息:
    • index - 循环的序号,从0开始。
    • number - 循环的序号,从1开始。
    • even - 对于偶数项为真(0, 2, 4, ...)。
    • odd - 对于奇数项为真(1, 3, 5, ...)。
    • start - 对于起始循环为真(index 0)。
    • end - 对于最后的循环为真。
    • first - 对于组中的某个数据第一次出现的时候为真。参见下面的注意。
    • last - 对于组中的某个数据最后一次出现的时候为真。参见下面的注意。
    • length - 序列的长度,即循环总数。
    • letter - 用小写字母表示的循环序号。比如"a" - "z", "aa" - "az", "ba" - "bz", ..., "za" - "zz", "aaa" - "aaz",等等。
    • Letter - 用大写字母表示的循环序号。
    • roman - 以小写罗马数字表示的循环序号,比如:"i", "ii", "iii", "iv", "v", 等等。
    • Roman - 以大写罗马数字表示的循环序号。

    你可以通过路径表达式或Python表达式访问循环变量。在路径表达式中,需要用三部分组成名称,即repeat、语句变量名称和要访问的变量名称。比如:
    repeat/item/start
    在Python表达式中,使用字典方法来访问信息,比如:
    python:repeat['item'].start
    除了start、end和index,所有repeat变量的属性都是方法。因此,当你用Python表达式时,必须这样来调用:
    python:repeat['item'].length()
    ** 注意 **
    first和last适用于过滤序列。它们试图根据相同值把序列分成组。如果提供了一个路径,那么根据这个路径取得的数值进行分组,否则使用数据项的值。
    你可以通过传递参数提供路径,比如"python:repeat['item'].first(color)",或通过repeat变量附加路径,比如,
    "repeat/item/first/color"。
    8.4. 例子
    对字符串序列进行循环:
       
    插入表格行,使用变量repeat显示行号:
      
         1
         Widget
         $1.50
      
    嵌套的循环:
      
       
          1 * 1 = 1
       
      
    插入对象,按照meta-type进行分组:
      Meta Type
      Object ID
      
    注意,上边例子中的对象应该已经按照meta-type进行了排序。
    9. replace: 替换元素
    9.1. 句法
    tal:replace 句法:
    argument ::= (['text'] | 'structure') expression
    9.2. 描述
    tal:replace语句的作用是用动态内容替换一个元素。替换的内容可以是文本或结构。表达式中可加上类型前缀。表达式结果会自动转换成字符类
    型。如果使用了前缀structure,则会在输出文本中保持特殊字符不变;否则会进行转换:即把 "&" 转换成 "&amp",
    把"" 转换成 ">"。
    如果为nothing,则只删除元素。如果为默认值,元素保持不变。
    9.3. 例子
    插入模板标题的两种方式:
    Title
    Title
    插入HTML/XML:
    插入nothing(空):
    This element is a comment.
    9.4. 参见
    tal:content
    10. TALES 概述
    模板属性语言表达式句法(TALES)描述了用于TAL和METAL的表达式。TALES提供了多种表达类型。
    以下是基本的TALES句法:
    Expression  ::= [type_prefix ':'] String
    type_prefix ::= Name
    以下是一些例子:
    a/b/c
    path:a/b/c
    nothing
    path:nothing
    python: 1 + 2
    string:Hello,
    ${user/getUserName}
    表达式前边可加上可选的类型前缀。如果不指定一个前缀,默认为路径表达式。
    10.1. TALES表达式类型:
    • path 表达式 - 根据路径确定数值。
    • exists 表达式 - 测试路径是否有效。
    • nocall 表达式 - 根据路径定位一个对象。
    • not 表达式 - 逻辑非表达式
    • string 表达式 - 字符串格式
    • python 表达式 - 运行Python表达式

    10.2. 内建名称
    TALES表达式中可使用以下名称:
    • nothing - 用于表示空值的特殊值。
    • default - 用于指定不可替换的文本。
    • options - 传递给模板的关键字参数。通常出现在通过方法和脚本调用模板的时候。
    • repeat - tal:repeat语句中的repeat变量。
    • attrs - 包含当前语句初始属性值的字典。
    • CONTEXTS - 标准名称的列表。用于访问隐藏的内建变量。
    • root - 系统中最顶级的对象:根文件夹。
    • here - 应用模板的对象。
    • container - 模板所属的文件夹。
    • template - 模板本身。
    • request - 请求对象。
    • user - 已验证用户对象。
    • modules - 可以访问的模块。

    注意 root, here, container, template, request, user, 和 modules是可选的名称,TALES标准中不要求必须使用。
    10.3. 参见
    TAL Overview
    METAL Overview
    exists expressions
    nocall expressions
    not expressions
    string expressions
    path expressions
    python expressions
    11. TALES Exists 表达式
    11.1. 句法
    Exists 表达式句法:
    exists_expressions ::= 'exists:' path_expression
    11.2. 描述
    Exists表达式测试路径是否存在。如果路径存在返回真。当不能定位一个对象时,返回假。
    11.3. 例子
    测试一个表单变量:
       Please enter a number between 0 and 5
    注意,此时不能使用 not:request/form/number,这是由于如果变量number存在并为0,表达式值将为真。
    12. TALES Nocall 表达式
    12.1. 句法
    Nocall 表达式句法:
    nocall_expression ::= 'nocall:' path_expression
    12.2. 描述
    Nocall 表达式避免了调用路径表达式的结果。
    通常路径表达式会调用对象。也就是说,如果对象是函数、脚本方法或其它可执行对象,则表达式会调用这些对象运行的结果。大多数情况下需要这样,但不
    总需要这样。例如,如果你想通过一个变量使用DTML文档,然后调用它的属性,此时就不能使用通常的路径表达式,否则会得到文档运行后的字符串。
    12.3. 例子
    使用nocall得到文档属性:
    Id: Title
    对一个函数使用nocall表达式:
    这个例子定义了一个变量join,它绑定给string.join函数。
    13. TALES Not 表达式
    13.1. 句法
    Not 表达式句法:
    not_expression ::= 'not:' expression
    13.2. 描述
    Not表达式先对expression字符串求值,然后返回它的布尔中的逻辑非值。如果提供的表达式求值后不是一个布尔值,则会根据以下规则转换成布尔类型:
    • 数字 0 为假
    • 正数和负数为真
    • 空的字符串或其它序列为假
    • 非空的字符串或其它序列为真
    • 空值为假,比如:void, None, Nil, NULL等等。
    • 其它值为真。
      如果没有提供expression字符串,会引发错误。
      13.3. 例子
      测试一个序列:
         There are no contained objects.
      14. TALES Path 表达式
      14.1. 句法
      Path 表达式句法:
      PathExpr    ::= Path [ '|' Expression ]
      Path        ::= variable [ '/' PathSegment ]*
      variable    ::= Name
      PathSegment ::= ( '?' variable ) | PathChar+
      PathChar    ::= AlphaNumeric | ' ' | '_' | '-' | '.' | ',' | '~'
      14.2. 描述
      路径表达式由一个路径组成,也可以在后边通过竖线符号(|)增加另外一个表达式,如果前一个表达式无效则使用后一个。路径由一个或多个非空字符串组
      成,用/分开。第一个字符串必须为一个变量名称(内建变量或用户定义的变量),其余部分可以包含字母、数字、空格和符号"_","-",".","~"。
      表达式中可以使用符号?表示一个动态变量,这个变量必须是一个字符串,运行时会替换成对应的字符串。
      例如:
      request/cookies/oatmeal
      nothing
      here/some-file 2001_02.html.tar.gz/foo
      root/to/branch | default
      request/name | string:Anonymous Coward
      here/?tname/macros/?mname
      当对表达式求值时,从左到右依次处理路径。
      如果出现错误,显示错误信息。
      附加的表达式可以是任何TALES表达式。比如,request/name | string:Anonymous
      Coward,就是一个有效的路径表达式。通过这个表达式,可以提供默认值。也可以提供多个附加的路径表达式,比如,first | second |
      third | nothing。
      如果没有路径,则为nothing。
      由于每个路径必须以一个变量名称开始,因此这个起始变量应该能够找到相应的对象才行。参见前边列出的内建变量。变量名称先在本地搜索,然后在内建变
      量列表中搜索,因此内建变量就像Python中内建的变量一样。也可以在变量名称前声明范围。你也可以直接通过CONTEXTS访问内建变量,比如,
      CONTEXTS/root, CONTEXTS/nothing。
      14.3. 例子
      插入一个cookie变量或一个属性:
        preference
      插入用户名称:
        User name
      15. TALES Python 表达式
      15.1. 句法
      Python 表达式句法:
      任何有效的Python语言表达式
      15.2. 描述
      Python表达式在安全限制环境内对Python代码求值。Python表达式和脚本对象和DTML中的变量表达式一样。
      15.2.1. 安全限制
      Python表达式的限制和脚本对象中的一样,这些限制包括:
      访问限制 Python 表达式受到Zope许可和角色安全的限制。另外,表达式还不能访问那些名称用下划线开头的对象。 写入限制 Python表达式不能更改Zope对象属性。
      15.2.2. 内建函数
      Python表达式和脚本对象中的内建函数一样,但增加了一些。
      标准的内建函数包括: None, abs, apply, callable, chr, cmp, complex, delattr,
      divmod, filter, float, getattr, hash, hex, int, isinstance, issubclass,
      list, len, long, map, max, min, oct, ord, repr, round, setattr, str,
      tuple.
      range和pow函数不能生成非常巨大的数值和序列。
      另外,还可以使用:DateTime,test,same_type。参考 DTML 函数部分。
      最后,可以在Python表达式中使用这些函数:
      path(string) 对一个TALES path表达式求值。 string(string) 对一个TALES string表达式求值。 exists(string) 对一个TALES exists表达式求值。 nocall(string) 对一个TALES nocall表达式求值。
      15.2.3. Python 模块
      可以使用默认提高的模块,也可以增加模块。访问模块的方式可以通过路径表达式,比如:modules/string/join,也可以在Python中使用module映射对象,比如:modules['string'].join。以下是默认的模块:
      string string模块。注意,模块中的大多数函数也可以通过字符串对象的方法进行访问。 random 随机模块。 math 数学模块。 sequence 具有强大排序功能的模块。 Products.PythonScripts.standard 提供各种HTML格式处理函数。 ZTUtils 提供批块处理功能。 AccessControl 提供安全和权限检查功能。
      15.2.4. 例子
      使用一个模块,从列表中随机选择一个数据项:
        a random number between one and five
      字符串处理,把用户名变成大写格式:
        User Name
      数学处理,把图像大小转换成兆字节:
        12.2323
      处理字符串格式,把浮点型格式为两个小数位:
        13.56
      16. TALES String 表达式
      16.1. 句法
      String 表达式句法:
      string_expression ::= ( plain_string | [ varsub ] )*
      varsub            ::= ( '$' Path ) | ( '${' Path '}' )
      plain_string      ::= ( '$$' | non_dollar )*
      non_dollar        ::= any character except '$'
      16.2. 描述
      字符串表达式按照文本处理字符串。如果没有提供字符串,则为空。字符串中可以通过$name或${path}格式使用变量,其中name为变量名称,path为路径表达式。如果要插入$符号,需要使用$$。
      16.3. 例子
      处理字符串:
        Spam and Eggs
      使用路径:
         total: 12
      包含一个$符号:
         cost: $42.00
      17. METAL 概述
      宏扩展模板属性语言(METAL)用于处理HTML/XML宏(Macro)。它可以结合TAL和TALES一起使用。
      宏提供了一种共享模板数据的方式。如果宏发生了变化,那么相应的共享数据也会发生变化。另外,宏可以扩展,从而具有最终结果的样子,方便编辑处理。
      17.1. METAL 名称空间
      METAL名称空间URI定义为:
      xmlns:metal="http://xml.zope.org/namespaces/metal"
      当创建内容类型具有text/html的模板时,Zope不要求声明XML名称空间。但对于其它类型则需要声明。
      17.2. METAL 语句
      METAL定义的语句包括:
    • metal:define-macro - 定义一个宏。
    • metal:use-macro - 使用一个宏。
    • metal:define-slot - 定义一个宏定制点。
    • metal:fill-slot - 定制一个宏

    参见
    TAL Overview
    TALES Overview
    metal:define-macro
    metal:use-macro
    metal:define-slot
    metal:fill-slot
    18. define-macro: 定义一个宏
    18.1. 句法
    metal:define-macro 句法:
    argument ::= Name
    18.2. 描述
    metal:define-macro语句定义一个宏。通过语句表达式进行定义,有效返回是当前所在的元素和下级元素。
    可以通过模板的macros对象调用宏定义。比如,在模板master.html中定义了宏header,那么你可以使用路径表达式master.html/macros/header访问这个宏。
    18.3. 例子
    简单的宏定义:
      Copyright 2001, Foobar Inc.
    参见
    metal:use-macro
    metal:define-slot
    19. define-slot: 定义一个宏定制点
    19.1. 句法
    metal:define-slot 句法:
    argument ::= Name
    19.2. 描述
    metal:define-slot语句定义了一个宏定制点,或内容块(slot)。当使用一个宏时,这个内容块可以替换成其它内容。内容块定义提供了默认的内容。如果不调用内容块,则显示默认的内容。
    metal:define-slot语句必须在metal:define-macro 之中。
    内容块的名称必须唯一。
    19.3. 例子
    简单的内容块定义:
      Hello World
    这个例子定义了一个宏和一个名为name的内容块。当你使用这个宏的时候,可以在b元素中添加进定制的内容。
    19.4. 参见
    metal:fill-slot
    20. fill-slot: 定制一个宏
    20.1. 句法
    metal:fill-slot 句法:
    argument ::= Name
    20.2. 描述
    metal:fill-slot语句通过替换宏中的内容块来定制宏。
    metal:fill-slot 语句必须在metal:use-macro中使用。
    内容块名称必须唯一。
    如果宏中不存在指定的内容块,则删除这个内容块。
    20.3. 例子
    先定义宏:
      Hello World
    你可以这样来填充内容块name:
      Hello Kevin Bacon
    20.4. 参见
    metal:define-slot
    21. use-macro: 使用一个宏
    21.1. 句法
    metal:use-macro 句法:
    argument ::= expression
    21.2. 描述
    metal:use-macro语句用宏替换当前元素中的内容。expression描述了一个宏定义。
    expression将生成一个路径表达式,用来指向另外一个模板中定义的宏。参见metal:define-macro部分。
    扩展宏的效果就是从另外一个文档或当前文档中提取部分内容,然后放进当前元素之中,即替换当前的内容。原来的内容保持不变,如果使用了内容块,则内容块中使用新的内容。
    当扩展宏时,使用metal:use-macro语句。
    21.3. 例子
    基本用法:
       header macro from defined in other.html template
    这个例子引用了在other.html模板中定义的header。当扩展这个宏时,p元素和它的内容将替换成宏中的内容。
    21.4. 参见
    metal:define-macro
    metal:fill-slot
    22. ZPT特定的行为
    Zope页面模板的行为几乎完全可以通过TAL、TALES和METAL进行描述。但还有一些特定的行为。
    HTML支持的特性
    当一个页面模板的内容类型设置为text/html,处理过程会有些不同于其它内容类型。在TAL名称空间中讲过,HTML不需要声明名称空间,默认>提供TAL和METAL名称空间。
    HTML文档采用非XML解析器,因此可以处理一些不符合XML要求的标记符。特别是那些没有结束标记符的元素,比如段落和列表,但还不能认为
    >
    是错误,除非它们是语句元素。这样就容易导致错误,比如使用用元素,但不嵌套在中,此时由于标记符,则会引发一个NestingError错误。因此解决的方法是使用。
    没有合拢的语句元素通常认为是错误,因此应该尽量指明合拢的标记符。对于那些没有结束标记符的元素,比如image和input元素,不要求加>上合拢标记符或使用XHTML中的格式。
    某些布尔属性,比如checked和selected,在tal:attributes中处理方式不同。数值为真或假。如果为真,则会处理成
    attr="attr"格式,如果为假,则会忽略。如果值为default,则此时,如果属性已经存在认为是真,不存在为假。比如:
    结果为:
    对于:
    将生成:
    这种处理方式可以在所有的浏览器中正确显示。