Package gluon :: Module template
[hide private]
[frames] | no frames]

Source Code for Module gluon.template

  1  """ 
  2  This file is part of web2py Web Framework (Copyrighted, 2007) 
  3  Developed by Massimo Di Pierro <mdipierro@cs.depaul.edu> 
  4  License: GPL v2 
  5  """ 
  6   
  7  import re, cgi, sys, os 
  8  from restricted import * 
  9   
 10  __all__=['reindent','parse_template'] 
 11   
 12  re_write=re.compile('\{\{=(?P<value>.*?)\}\}',re.DOTALL) 
 13  re_html=re.compile('\}\}.*?\{\{',re.DOTALL) 
 14  #re_strings=re.compile('((?:""").*?(?:"""))|'+"((?:''').*?(?:'''))"+'((?:""").*?(?:"""))|'+"((?:''').*?(?:'''))" 
 15   
 16  PY_STRING_LITERAL_RE= r'(?P<name>'+ \ 
 17    r"[uU]?[rR]?(?:'''(?:[^']|'{1,2}(?!'))*''')|" +\ 
 18                r"(?:'(?:[^'\\]|\\.)*')|" +\ 
 19              r'(?:"""(?:[^"]|"{1,2}(?!"))*""")|'+ \ 
 20                r'(?:"(?:[^"\\]|\\.)*"))' 
 21  re_strings=re.compile(PY_STRING_LITERAL_RE,re.DOTALL) 
 22   
 23  re_include_nameless=re.compile('\{\{\s*include\s*\}\}') 
 24  re_include=re.compile('\{\{\s*include\s+[\'"](?P<name>.*?)[\'"]\s*\}\}') 
 25  re_extend=re.compile('^\s*\{\{\s*extend\s+[\'"](?P<name>[^\']+)[\'"]\s*\}\}') 
 26   
27 -def reindent(text):
28 lines=text.split('\n') 29 new_lines=[] 30 credit=k=0 31 for raw_line in lines: 32 line=raw_line.strip() 33 if line[:5]=='elif ' or line[:5]=='else:' or \ 34 line[:7]=='except:' or line[:7]=='except ' or \ 35 line[:7]=='finally:': 36 k=k+credit-1 37 if k<0: k=0 38 new_lines.append(' '*k+line) 39 credit=0 40 if line=='pass' or line[:5]=='pass ': 41 credit=0 42 k-=1 43 if line=='return' or line[:7]=='return ' or \ 44 line=='continue' or line[:9]=='continue ' or \ 45 line=='break' or line[:6]=='break': 46 credit=1 47 k-=1 48 if line[-1:]==':': k+=1 49 text='\n'.join(new_lines) 50 return text
51
52 -def replace(regex,text,f):
53 i=0 54 output=[] 55 for item in regex.finditer(text): 56 output.append(text[i:item.start()]) 57 output.append(f(item.group())) 58 i=item.end() 59 output.append(text[i:len(text)]) 60 return ''.join(output)
61
62 -def parse_template(filename,path='views/',cache='cache/'):
63 filename=filename 64 ## 65 # read the template 66 ## 67 try: data=open(os.path.join(path,filename),'rb').read() 68 except IOError: raise RestrictedError('Processing View '+filename, 69 '','Unable to find the file') 70 # check whether it extends a layout 71 while 1: 72 match=re_extend.search(data) 73 if not match: break 74 t=os.path.join(path,match.group('name')) 75 try: parent=open(t,'rb').read() 76 except IOError: raise RestrictedError('Processing View '+filename,data,'','Unable to open parent view file: '+t) 77 data=re_include_nameless.sub(re_extend.sub('',data,1),parent) 78 79 ## 80 # check whether it includes subtemplates 81 ## 82 while 1: 83 match=re_include.search(data) 84 if not match: break 85 t=os.path.join(path,match.group('name')) 86 try: child=open(t,'rb').read() 87 except IOError: raise RestrictedError('Processing View '+filename,data,'','Unable to open included view file: '+t) 88 data=re_include.sub(child,data,1) 89 90 ## 91 # now convert to a python expression 92 ## 93 text='}}%s{{'%re_write.sub('{{response.write(\g<value>)}}',data) 94 text=replace(re_html,text,lambda x: '\nresponse.write(%s,escape=False)\n'%repr(x[2:-2])) 95 text=replace(re_strings,text,lambda x: x.replace('\n','\\n')) 96 return reindent(text) 97 98 if __name__=='__main__': 99 print parse_template(sys.argv[1],path='../applications/welcome/views/') 100