码迷,mamicode.com
首页 > 编程语言 > 详细

用python写自定义模板

时间:2014-12-29 13:37:59      阅读:292      评论:0      收藏:0      [点我收藏+]

标签:

模板语法有点像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_statement
import re
import 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写自定义模板

标签:

原文地址:http://www.cnblogs.com/nagi/p/4191471.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!