含有章节索引的中文 文章模板
-- limodou [DateTime(2004-08-27T01:30:31Z)] TableOfContents
Otter模板测试记录
这是我记录使用meteor生成Otter模板的记录
测试准备
- 分析Otter模板的整体框架
- 分析结果如下:
- 整个模板数据只有一个,而meteor对于每一个模板均需要一个数据字典。当然是可以考虑共用一个。
- OtTDict.py 确如Zoom.quiet所讲是一个体力活,它完成XML数据字典转换为模板变量值的过程,替换过程是一个通用的方法。不过一些模板的循环处理都是要通过程序才可以实现。编程量相对大。
- 测试准备:
- 只对pcon-pmsg.py进行测试,因此先要将其改成meteor要求的格式。因为在原模板中不能定义子模板,因此还要分离相应的子模板。文件查看:attachment:pcon-pmsg_tmpl.py
- 下面只显示主要部分,注释什么地去掉了。同时模板变量的定义保持原样。
- 只对pcon-pmsg.py进行测试,因此先要将其改成meteor要求的格式。因为在原模板中不能定义子模板,因此还要分离相应的子模板。文件查看:attachment:pcon-pmsg_tmpl.py
1 #coding=utf-8
2 from Template import T
3
4 main=T("""# -*- coding: utf-8 -*-
5 #...略去注释
6
7 from ###Lprotoname###.message import ###MsgBase###
8 import struct
9
10 class ###Uprotoname###PMessage(###MsgBase###.ByteMessage):
11 \"\"\"二进制流连接消息基类\"\"\"
12 def __init__(self):
13 # 消息头
14 self.head = ###MsgBase###.ByteMessageHead(self)
15 # 消息体
16 self.body = ###MsgBase###.ByteMessageBody(self)
17 # 消息工具
18 self.msgutilcls = ###Uprotoname###PMessageUtil
19 # 协议名称
20 self.protocolname = '###Lprotoname###p'
21 # 当前的消息名称
22 self.msgname = ''
23
24 ###Commands###
25
26 class ###Uprotoname###PMessageUtil(###MsgBase###.ByteMessageUtil):
27 \"\"\"二进制长连接消息处理工具类\"\"\"
28 def __init__(self):
29 pass
30
31 # 消息定义
32 ###Uprotoname###PMessageUtil.commandinfo = {
33 ###Commandsinfo###
34 }
35
36 # 通过名称查出消息ID的结构定义
37 ###Uprotoname###PMessageUtil.nametoid = {}
38 for k in ###Uprotoname###PMessageUtil.commandinfo.keys():
39 ###Uprotoname###PMessageUtil.nametoid[###Uprotoname###PMessageUtil.commandinfo[k]] = k
40
41 """)
42
43 Commands = T(""" def pack_###Lprotoname###p_###commandname###(self, fields):
44 ###packcontent###
45
46 def unpack_###Lprotoname###p_###commandname###(self, fields):
47 ###unpackcontent###
48
49 """)
50
51 Lprotoname = T("###lpname###")
52 Uprotoname = T("###upname###")
53 packcontent = T('')
54 unpackcontent = T('')
55 Commandsinfo=T(" ###flag### : '###name###',\n")
原来的模板被我分成:
main Commands packcontent unpackcontent Lprotoname Uprotoname Commandsinfo
主模板为main, 其它为子模板,同时Commands中还有子模板。
对于象lpname,upname, flag, name没有定义成模板形式,因此是外部变量。
而packcontent和unpackcontent内容为空,因为它们的替换处理将使用自编程序完成。原来我想模板替换,只要有数据就可以替换,但在处理pcon-pmsg.py时发现,有时并不总是能够满足需求。因此我在meteor中增加了编程接口。只不过这个编程接口只可以用于模板变量,对于外部变量不能使用。但是如果你想对一个外部变量进行单独处理的话,可以把它定义为一个模板变量。因为meteor区分一个替换模式是模板变量还是外部变量只是看在模板中有无定义,内容可以为空。
对于packcontent和unpackcontent对应的内容生成的结果为(这里是meteor生成的结果,与使用Otter生成的还是有些差别,不过差不多):
def pack_ussp_connect(self, fields): return struct.pack('6s16sI8s', fields['system_id'], fields['auth_source'], fields['version'], fields['time_stamp'], ) def unpack_ussp_connect(self, fields): self.body.fields['system_id'],\ self.body.fields['auth_source'],\ self.body.fields['version'],\ self.body.fields['time_stamp'],\ =struct.unpack('6s16sI8s',packet)
与XML文件对比一下,你会发现,这里的内容是由一组字段生成的,同时象6s16sI8s是从所有字段相应的属性提出来的合在一起的。因此这里需要某些逻辑处理的功能。OtTDict.py中复杂的处理就集中在这里。meteor模板支持模板变量间的引用、模板变量自身的重复、模板变量间的嵌套,但不会对数据做特殊处理,只是替换。象这里所要求的,还要进行处理,meteor就做不到了。因此,我还是使用了编程来实现这段信息的处理。
不过整个meteor的处理还是以数据为中心驱动的。如果需要重复多次,只要提供一个字典的列表就可以重复多次了。