- #coding:utf- 8
- __author__="sdm"
- __author_email='sdmzhu3@gmail.com'
- __date__ ="$2009-8-25 21:04:13$"
- '' '
- pytpl 类似 php的模板类
- '' '
- import sys
- import StringIO
- import os.path
- import os
- #模 板的缓存
- _tpl_cache={}
- class Pytpl:
- def __init__(self,tpl_path='./' ):
- self.tpl_path=tpl_path
- self.data={}
- self.output = StringIO.StringIO()
- pass
- def set(self,name,value):
- '' '
- 设 置模板变量
- '' '
- self.data[name]=value;
- pass
- def get(self,name):
- '' '
- 得 到模板变量
- '' '
- t={}
- return t.get(name, '' )
- pass
- def tpl(self,tplname):
- '' '
- 渲 染模板
- '' '
- f=self.tpl_path+tplname
- if not os.path.exists(f):
- raise Exception('tpl:[%s] is not exists' % f)
- mtime=os.stat(f).st_mtime
- if not _tpl_cache.has_key(f) or _tpl_cache[f][ 'time' ]<mtime:
- src_code=self.__compile__(open(f).read())
- try :
- t=open(f+'.py' , 'w' )
- t.write(src_code)
- t.close()
- except:
- pass
- py_code=compile(src_code, f+'.py' , 'exec' )
- _tpl_cache[f]={'code' :py_code, 'time' :mtime}
- else :
- py_code= _tpl_cache[f]['code' ]
- exec(py_code, {'self' :self}, self.data)
- return self.output.getvalue()
- def execute(self,code,data,tplname):
- '' '
- 执 行这个模板
- '' '
- py_file_name=tplname+'.py'
- f=open(py_file_name,'w' )
- f.write(code)
- f.close()
- execfile(py_file_name, {'self' :self}, data)
- def __compile__ (self,code):
- '' '
- 编 译模板
- 查找 <?标记
- '' '
- tlen=len(code);
- flag_start='<?'
- flag_end='?>'
- # 默认普通标记
- status=0
- i=0
- #分块 标记
- pos_end=0
- pos_start=0
- #缩 进
- global indent
- indent=0
- py_code=[]
- def place_t_code(c,t_indent):
- '' '
- 基 本的代码处理
- '' '
- global indent
- if (c[ 0 ]== '=' ):
- return ( ' ' * 4 *indent) + 'echo ( /'%s/' % (' +c[ 1 :]+ '))'
- lines=c.split("/n" )
- t=[]
- for i in lines:
- indent2=indent
- tmp=i.strip(" /n/r" )
- c=tmp[len(tmp)-1 :len(tmp)]
- # 判定最后一个字符
- if (c== '{' ):
- indent+=1
- tmp=tmp[0 :len(tmp)- 1 ]+ ":"
- elif(c=='}' ):
- indent-=1
- tmp=tmp[0 :len(tmp)- 1 ]
- t.append((' ' * 4 *indent2) +tmp )
- return "/n" .join(t)
- while 1 :
- if i>=tlen: break
- c=code[i];
- if status== 0 :
- # 编译加速
- pos_start=code.find(flag_start,pos_end);
- if (pos_start>- 1 ):
- s=code[pos_end:pos_start]
- t_code= 'echo ( ' +repr(s)+ ')'
- t_code=' ' *indent* 4 +t_code
- if s:
- py_code.append(t_code)
- i=pos_start
- last_pos=i
- # 进入代码状态
- status=1
- continue
- else :
- # 没有没有找到
- pos_start=tlen
- t_code='echo ( ' +repr(code[pos_end:pos_start])+ ' ) '
- t_code=' ' *indent* 4 +t_code
- py_code.append(t_code)
- break
- if status== 1 :
- # 查找结束标记
- pos_end=code.find(flag_end,i)
- if (pos_end>- 1 ):
- # 需要跳过<? 这个标记
- t_code=place_t_code(code[pos_start+2 :pos_end],indent)
- # 跳过?>结束标记
- pos_end+=2
- py_code.append(t_code)
- else :
- # 没查找到直接结束
- pos_end=tlen
- # 需要跳过<? 这个标记
- t_code=place_t_code(code[pos_start+2 :pos_end],indent)
- py_code.append(t_code)
- break
- status=0
- i=pos_end
- pass
- i+=1
- py_code_str="#coding:utf-8/nimport sys;global echo;echo=self.output.write/n"
- py_code_str+="/n" .join(py_code)
- py_code_str=py_code_str.replace("/t" , " " )
- return py_code_str
- def test():
- tpl=Pytpl('./' );
- tpl.set('title' , '标题3' )
- print tpl.tpl('test.html' )
- pass
- if __name__ == "__main__" :
- test()
分享一个简单的python模板引擎
最新推荐文章于 2024-08-14 12:07:21 发布