karrigell中forum实例的showThread.pih学习笔记

karrigell中forum实例的showThread.pih学习笔记

中午继续学习karrigell,想起了昨天的index.pih中有2个链接是指向showThread.pih和writeMessage.pih的,先看下showThread.pih,按照程序执行的流程,先就导入了这几个模块:
import time,cStringIO, k_utils
import forumDb
db = forumDb.db
time_format = forumDb.get_time_format(ACCEPTED_LANGUAGES)
大致扫描了下先:
<%
indent=0
showThread(rootMsg)
%>
定义了一个变量indent=0,然后是调用了函数showThread(rootMsg),找到这个函数的定义:
def showThread(msg):
    # shows the thread beginning at msg
    # only one line per message, indented
    global indent
    display_line(msg,indent)
    all.write(display_full(msg))
    res=[]
    res=[ m for m in threadMsgs if m.parent==msg.recno ]   
    res.sort(compDate)
    for childmsg in res:
        indent+=1
        showThread(childmsg)
        indent-=1
display_line(msg,indent),呼呼,showThread()中又出现一个函数调用,那继续沿着这个路线,先看看display_line()的定义:
def display_line(msg,indent):
    print '<tr>'
    print '<td>%s<a href="#%s">%s</a></td>' \
        %(" "*indent*2,msg.recno,msg.title)
    print '<td>%s</td>' %msg.author
    print '<td>%s</td>' %msg.date.strftime(time_format)
    print '</tr>'
结合forum的使用实践来看,这个函数用来就是显示在每个主题上面的第一个表格,里面的信息就是主题信息和回帖的信息总揽." "*indent*2 用来控制每条回复的消息前面的空格数目,类似于树型的结构.呼呼,习惯了直接呼叫几楼来做答复,还有点不习惯这样的用缩进来表示回复关系.%msg.date.strftime(time_format)表示格式化后的时间.
返回到showThread()中,新发现:
all.write(display_full(msg))
all.write(),想起了导入的cStringIO,那他写的入的是个什么样的字符串呢?display_full(msg),又是一个函数,而且根据all.write(),猜想这个函数会返回一个字符串.找一下,看见了,果然返回res这个字符串:
def display_full(msg):
    res="""<tr>
    <td valign="top"><a name="%s">%s</td>
    <td valign="top">%s</td>
    <td valign="top">%s</td>
    </tr>
    <tr>
    <td>%s</td>
    <td> </td>
    <td valign="bottom"><a href="%s?state=answer&messageId=%s">
        %s</a></td>
    </tr>
    <tr><td colspan="3"><hr></td></tr>""" \
        %(msg.recno,msg.title,msg.author,msg.date.strftime(time_format),
            msg.content,"writeMessage.pih",msg.recno,_("Answer"))
    return res
faint,这个函数稍微复杂点.不过一看,好多都是用来控制表格的,msg.recno是每条记录在数据库中的索引号,每条信息都具有自己唯一的一个recno,但是同一个thread,可以被多个记录共有,比如一个主题的thread是1,那么回复这个主题的所有帖子,thread都是1.最后一个链接中,对应的是,"writeMessage.pih",msg.recno,_("Answer"),表示这个链接指向writeMessage.pih写信息的页面,state=answer是在writeMessage.pih要传递的一个变量,用来确定writeMessage.pih中是写的新主题还是仅仅是回复.messageId=%s对应的是msg.recno,messageId也是要传递给writeMessage.pih的parent变量,以确定这个回复贴是属于哪个帖子的'子贴',如果是发表的新贴,state的值是new,parent变量直接为-1.哦?中间有个不起眼的<hr>,看了一下,的确,每条信息下都有条水平线作为分隔.
再次回到showThread()中,继续:

res=[]
res=[ m for m in threadMsgs if m.parent==msg.recno ]   
res.sort(compDate)
for childmsg in res:
    indent+=1
    showThread(childmsg)
    indent-=1
出现递归?恩,真的是递归,用来干什么的呢,indent+=1,indent-=1,看来是用来控制帖子缩进的格式的,
res=[ m for m in threadMsgs if m.parent==msg.recno ] ,一个列表筛选,m.parent==msg.recno,把属于回复同一个话题的帖子放在一起(如果没有一个m.parent和msg.recno相等,说明没有回复,res为空,后面的递归也不会做了),这里似乎还是在建立一个类似树的结构.先跳过res.sort(compDate),估计他是用来排序的.最后用childmsg遍历整个res列表,递归处理他们的缩进关系.
接着看看,res.sort(compDate):
def compDate(msg1,msg2):
    return cmp(msg2.date,msg1.date)
按降序对列表res排序.继续阅读:
发现so=Session().哦?目前还没看见和他有关的东东,跳过先.
# retrieves all messages of the thread in one SQL request
threadMsgs=db.select('forum.tbl',['thread'],["==%s" %_thread],returnType='object')
# root of the thread
for msg in threadMsgs:
    if msg.parent==-1:
        break
rootMsg=msg
从数据库中取出index.pih中时相应请求对应的thread记录.因为一个thread在数据库里可以对应多条记录,所以筛选了一下下:
for msg in threadMsgs:
    if msg.parent==-1:
        break
rootMsg=msg
找到parent==-1的记录,就是主题rootMsg了,哦,对了,想起了开始的showThread(rootMsg),呼呼.
最后看看:
<table class="forum">
<tr class="title">
<td><%_ "Title" %></td>
<td><%_ "By" %></td>
<td><%_ "Date" %></td>
</tr>
<%
indent=0
print all.getvalue()
%>
</table>
输出一个表格,没什么特别的,最后print all.getvalue(),恩,刚才的用过all.write(display_full(msg)).
基本把showThread.pih走了一遍,faint啊,writeMessage.pih比较内容不多,OK,这个demo基本理解了,下一个目标是wiki.咔咔
lz加油!