分享一个简单的python模板引擎

  1. #coding:utf- 8   
  2. __author__="sdm"   
  3. __author_email='sdmzhu3@gmail.com'   
  4.   
  5. __date__ ="$2009-8-25 21:04:13$"   
  6.   
  7. '' '  
  8. pytpl 类似 php的模板类  
  9.   
  10.   
  11. '' '  
  12. import  sys  
  13. import  StringIO  
  14. import  os.path  
  15. import  os  
  16. #模 板的缓存  
  17. _tpl_cache={}  
  18. class  Pytpl:  
  19.   
  20.     def __init__(self,tpl_path='./' ):  
  21.         self.tpl_path=tpl_path  
  22.         self.data={}  
  23.         self.output = StringIO.StringIO()  
  24.         pass  
  25.   
  26.     def set(self,name,value):  
  27.         '' '  
  28.         设 置模板变量  
  29.         '' '  
  30.         self.data[name]=value;  
  31.         pass  
  32.   
  33.     def get(self,name):  
  34.         '' '  
  35.         得 到模板变量  
  36.         '' '  
  37.         t={}  
  38.         return  t.get(name, '' )  
  39.         pass  
  40.   
  41.     def tpl(self,tplname):  
  42.         '' '  
  43.         渲 染模板  
  44.         '' '  
  45.         f=self.tpl_path+tplname  
  46.         if  not os.path.exists(f):  
  47.             raise Exception('tpl:[%s] is not exists'  % f)  
  48.           
  49.         mtime=os.stat(f).st_mtime  
  50.   
  51.         if   not _tpl_cache.has_key(f) or  _tpl_cache[f][ 'time' ]<mtime:  
  52.             src_code=self.__compile__(open(f).read())  
  53.             try :  
  54.                 t=open(f+'.py' , 'w' )  
  55.                 t.write(src_code)  
  56.                 t.close()  
  57.             except:  
  58.                 pass  
  59.               
  60.             py_code=compile(src_code, f+'.py' , 'exec' )  
  61.             _tpl_cache[f]={'code' :py_code, 'time' :mtime}  
  62.               
  63.   
  64.         else :  
  65.             py_code= _tpl_cache[f]['code' ]  
  66.               
  67.         exec(py_code, {'self' :self}, self.data)  
  68.         return  self.output.getvalue()  
  69.   
  70.   
  71.     def execute(self,code,data,tplname):  
  72.         '' '  
  73.         执 行这个模板  
  74.         '' '  
  75.         py_file_name=tplname+'.py'   
  76.         f=open(py_file_name,'w' )  
  77.         f.write(code)  
  78.         f.close()  
  79.         execfile(py_file_name, {'self' :self}, data)  
  80.   
  81.     def __compile__ (self,code):  
  82.         '' '  
  83.         编 译模板  
  84.         查找 <?标记  
  85.         '' '  
  86.         tlen=len(code);  
  87.         flag_start='<?'   
  88.         flag_end='?>'   
  89.         # 默认普通标记  
  90.         status=0   
  91.         i=0   
  92.         #分块 标记  
  93.         pos_end=0   
  94.         pos_start=0   
  95.         #缩 进  
  96.         global indent  
  97.         indent=0   
  98.         py_code=[]  
  99.   
  100.         def place_t_code(c,t_indent):  
  101.             '' '  
  102.             基 本的代码处理  
  103.             '' '  
  104.             global indent  
  105.             if (c[ 0 ]== '=' ):  
  106.                 return  ( ' '  * 4 *indent) +   'echo ( /'%s/' % (' +c[ 1 :]+ '))'   
  107.             lines=c.split("/n" )  
  108.             t=[]  
  109.             for  i in lines:  
  110.                 indent2=indent  
  111.                 tmp=i.strip("   /n/r" )  
  112.                 c=tmp[len(tmp)-1 :len(tmp)]  
  113.                 # 判定最后一个字符  
  114.                 if (c== '{' ):  
  115.                     indent+=1   
  116.                     tmp=tmp[0 :len(tmp)- 1 ]+ ":"   
  117.                 elif(c=='}' ):  
  118.                     indent-=1   
  119.                     tmp=tmp[0 :len(tmp)- 1 ]  
  120.                 t.append((' '  * 4 *indent2) +tmp )  
  121.             return   "/n" .join(t)  
  122.   
  123.         while   1 :  
  124.             if  i>=tlen: break   
  125.             c=code[i];  
  126.             if  status== 0 :  
  127.                 # 编译加速  
  128.                 pos_start=code.find(flag_start,pos_end);  
  129.                 if (pos_start>- 1 ):  
  130.                     s=code[pos_end:pos_start]  
  131.                     t_code= 'echo ( ' +repr(s)+ ')'   
  132.                     t_code=' ' *indent* 4  +t_code  
  133.                     if  s:  
  134.                         py_code.append(t_code)  
  135.                     i=pos_start  
  136.                     last_pos=i  
  137.                     # 进入代码状态  
  138.                     status=1   
  139.                     continue   
  140.                 else :  
  141.                     # 没有没有找到  
  142.                     pos_start=tlen  
  143.                     t_code='echo ( ' +repr(code[pos_end:pos_start])+ ' ) '   
  144.                     t_code=' ' *indent* 4  +t_code  
  145.                     py_code.append(t_code)  
  146.                     break   
  147.             if  status== 1 :  
  148.                 # 查找结束标记  
  149.                 pos_end=code.find(flag_end,i)  
  150.                 if (pos_end>- 1 ):  
  151.                     # 需要跳过<? 这个标记  
  152.                     t_code=place_t_code(code[pos_start+2 :pos_end],indent)  
  153.   
  154.                     # 跳过?>结束标记  
  155.                     pos_end+=2   
  156.                     py_code.append(t_code)  
  157.                 else :  
  158.                     # 没查找到直接结束  
  159.                     pos_end=tlen  
  160.                     # 需要跳过<? 这个标记  
  161.                     t_code=place_t_code(code[pos_start+2 :pos_end],indent)  
  162.                     py_code.append(t_code)  
  163.                     break   
  164.                 status=0   
  165.                 i=pos_end  
  166.                 pass  
  167.             i+=1   
  168.   
  169.         py_code_str="#coding:utf-8/nimport sys;global echo;echo=self.output.write/n"   
  170.         py_code_str+="/n" .join(py_code)  
  171.         py_code_str=py_code_str.replace("/t""    " )  
  172.         return  py_code_str  
  173.   
  174.   
  175. def test():  
  176.     tpl=Pytpl('./' );  
  177.     tpl.set('title''标题3' )  
  178.     print tpl.tpl('test.html' )  
  179.   
  180.   
  181.     pass  
  182.   
  183.   
  184. if  __name__ ==  "__main__" :  
  185.     test() 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值