Python实现的简单模板引擎功能示例

时间:2022-10-30 19:01:30

本文实例讲述了Python实现的简单模板引擎功能。分享给大家供大家参考,具体如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#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程序设计有所帮助。

原文链接:http://blog.csdn.net/m190481164/article/details/5611713