首页 > 代码库 > 用python写自定义模板
用python写自定义模板
模板语法有点像php
!/usr/bin/env python"""#demo.py.html<html><?py include head.py.html ?><body> <?py extend test_for.py.html ?> <div> <pre> test if </pre> <?py if 2 > 1 ?> <p>Yes, it is</p> <?py else ?> <p>No it is not</p> <?py #endif ?> </div> <div> <pre> test def </pre> <?py def p() ?> <?py return ‘hello‘ ?> <?py #enddef ?> Wow! ${p()} </div></body></html>#head.py.html<head> <title>Demo Py Template</title></head>#test_for.py.html<div> <pre> test for <pre> <?py for _ in [‘a‘, ‘b‘, ‘c‘] ?> Hello ${_} #{_.upper()} <?py #endfor ?></div>""" from __future__ import absolute_import, division, print_function, with_statementimport reimport os.path class TemplateLoader(object): pass class DictLoader(object): pass class Template(object): #GLOBALS = {} def __init__(self, tempalte_path): self.tempalte_path = tempalte_path self.globals = { ‘t‘: lambda x: x, ‘xml_escape‘: xml_escape, ‘html_escape‘: html_escape, ‘e‘: escape } self.templates = { } def render(self, path, **kwrags): # the stemplae system local never be override _g = kwargs.update(self.globals) code = self.genarate(path, g) exec code in _g return _g[‘_tt_render‘]() def genarate(self, path, g): if path in self.templates: return self.templates[path](g) tempalte_path = os.path.join(self.tempalte_path, path) tempalte_func = TemplateParser(tempalte_path).compile() self.templates[path] = tempalte_func return tempalte_func(g) class TemplateParser(object): PY_TOKEN = re.compile(r‘<\?py\s*((?:[^=0-9]).*?)\s*\?>‘) PY_VAR_TOKEN = re.compile(r‘(?:[#$])\{(.*?)\}‘) def __init__(self, path2template, indent=None, include=False): self.path2template = path2template self.indent = indent or 1 self.buffer = ‘‘ self._include = include if not self._include: self.buffer += ‘def _tt_render():\n‘ self.puts(‘_buffer=[]‘) self.puts(‘_append=_buffer.append‘) def puts(self, line): self.buffer += self.indents + "%s" % (line) + ‘\n‘ def compile(self): code = self.parse() code = compile(code, ‘<string>‘, ‘exec‘, dont_inherit=True) return code def parse(self): f = open(self.path2template) lineno = 1 while True: line = f.readline() if not line: break self.parse_line(line, lineno) lineno += 1 if not self._include: self.puts(‘return "".join(_buffer)‘) f.close() return self.buffer def parse_line(self, line, lineno): # remove the whitespace line and comment line if not line.strip() or line.lstrip().startswith(‘#‘): return m = self.PY_TOKEN.search(line) if m: t = m.group(1) parts = t.split(‘ ‘, 1) if parts[0] in (‘from‘, ‘import‘): self.stmt(t) return if parts[0] == ‘include‘: self.include(parts[1]) return if parts[0] == ‘extend‘: self.extend(parts[1]) return if parts[0] in (‘for‘, ‘if‘, ‘with‘, ‘def‘, ‘class‘, ‘try‘): self.contoll(t) self.indent += 1 return if parts[0] in (‘else‘, ‘elif‘, ‘except‘): self.indent -= 1 self.contoll(t) self.indent += 1 return if parts[0] in (‘#end‘, ‘#endfor‘, ‘#endif‘, ‘#endtry‘, ‘#endclass‘, ‘#enddef‘, ‘#endwith‘): self.indent -= 1 return self.stmt(t) return # handle var token ms = self.PY_VAR_TOKEN.finditer(line) if ms: a = None end = 0 start = 0 l = ‘‘ for m in ms: t = m.group(1) start = m.start() b = line[end:m.start()] start = m.start() end = m.end() a = line[end:] if l: l += "+ ‘%s‘" % (b) + " + str(%s) " % (t) else: l = "‘%s‘" % (b) + " + str(%s) " % (t) if a and start: l += "+" + " %r" % (a) if l: self.stmt("_append(" + l + ")") return self.text(line) def text(self, content): content = self.indents + ‘_append(‘ + "%r" % (content) + ‘)\n‘ self.buffer += content def e(self, formator, t): self.puts(‘_append("‘ + formator + ‘"‘ + ‘ % ‘ + t + ")") def r(self): return ‘%r‘ def contoll(self, line): self.buffer += self.indents + line + ‘:\n‘ def stmt(self, stmt): self.buffer += self.indents + stmt + ‘ \n‘ @property def indents(self): return ‘ ‘ * self.indent def include(self, template): p = TemplateParser(template, include=True) self.buffer += p.parse() def extend(self, template): p = TemplateParser(template, self.indent, include=True) self.buffer += p.parse() if __name__ == ‘__main__‘: t = TemplateParser(‘demo.py.html‘) code = t.compile() ns = {} exec code in ns # print ns print(ns[‘_tt_render‘]())
用python写自定义模板
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。