1.变量是否存在
在我制作“翻译与评论”页面的时候,我有一个问题,就是“如何判断变量是否存在?”为什么会有这个问题呢?因为,我需要根据这个变量是否存在来决定显示或不显示某些信息。那么在PHP中我可以使用isset()函数,而在Zope中如何做呢?好象没有这样的函数。这个问题困扰了我几天,在我详细阅读了Zope在线Help中关于dtml-if的说明之后,终于清楚了。原文是这样的:
The if tag is a block tag. The if tag and optional elif tags take a condition variable name or a condition expression, but not both. If the condition name or expression evaluates to true then the if block is executed. True means not zero, an empty string or an empty list. If the condition variable is not found then the condition is considered false.
意思是说:“if 标签是一个块标签。if标签与可选的elif标签使用一个条件变量名或一个条件表达式,但不能同时使用。如果条件名或表达式计算为ture那么if块被执行。Ture表示非0,非空串或非空列。如果条件变量没有找到那么条件被认为false。
有了这个说明,我明白了,只要使用< dtml-if var >就可以知道变量是否有效了。当然,你也可以说如果它为0呢?当然如果有类似的情况,我们可以考虑把变量的取值设定为非0值即可,这样不应该出现值为空值的情况。
2.生成新变量
DTML Document和DTML Method中可以使用DTML语言进行简单的编程。在编程过程中我们可能需要生成一些变量,那么使用< dtml-let >就可以了。变量作为属性名,等号后面是取值,可以是表达式。要注意它是一个块语句,因此生成新的变量后一定要在结束前使用,否则就失效了。例如:
< dtml-let a="'all'">
< dtml-var a >
< /dtml-let >
这样我们定义了一个变量a,它是一个字符串,因此要用引号引起来。这里双引号表示属性值,其包含的内容才是真正的值。用双引号是符合html文档的要求。因此,如果只写a="all"那么表示a的值为变量all的值,而不是'all'。所以正确的写法应该是a="'all'"。
3.名字空间
关于这一点我还没有仔细地了解,因此只能讲一些体会。名字空间是你所使用的环境,它记录着你所能使用的所有的方法和变量。对于Zope来说,名字空间是一个栈的结构,它依据搜索对象的路径依次入栈。当调用一个变量或方法时,首先在栈顶的名字空间进行查找,如果没有找到,则向下查找,直到栈底。因此,最上面你所使用的名字空间应该是调用的对象。DTML Document是一个Zope对象,它具有自已的名字空间。因此在调用一个DTML Document时,Zope会首先在这个DTML Document中进行查找,然后再向下查找。而对于DTML Method就不同了,它使用调用者的名字空间。那么哪个是它的调用者呢?应该是它是上一个对象。可能是一个DTML Document或是一个容器如Folder。由于有这样的区别,因此我们在使用这两者时应特别注意。
4.变量的位置
因为在Zope中存在不同的名字空间,这样就可能在不同的名字空间存在相同的变量名。而Zope在搜索一个变量时先找最上层的名字空间,那么对于 REQUEST对象来说,它位于栈的下端,所以如果在某个上层对象存在一个与REQUEST中相同的变量时,我们首先得到的是上层对象的变量,那么有时我们想要的是REQUEST中的cookie值,如果才可以得到呢?一种通过限定,如< dtml-var expr="REQUEST.cookies['username']" >另一种方法是使用< dtml-with >标签。它可以将指定的对象名字空间提升到最前。如:< dtml-with REQUEST >。如果我们在后面加入only属性则表示,只在REQUEST名字空间中进行搜索而不搜索别的空间了。在这里,我有一些对”对象的属性与方法 “和”名字空间“混淆了,但有时它们是一样的。
5.REQUEST和RESPONSE
Zope定义了两个有趣的对象,REQUEST和RESPONSE。是不是象ASP中的东东。REQUEST存放上传时的html信息,如 cookie,form变量,CGI环境变量,及其它一些信息。RESPONSE则是应答。如回传的信息,头信息,设置cookie信息等等。有一点要注意,Zope不象PHP,它是全部处理正确后才可以返回,因此不象PHP中对于cookie的输出要放在所有其它的输出之前,而是可以放在任何位置。这一点非常方便。