首页 > 代码库 > bottle.py中的SimpleTemplate

bottle.py中的SimpleTemplate

import reclass SimpleTemplate(object):    re_block = re.compile(r‘^\s*%\s*((if|elif|else|try|except|finally|for|while|with).*:)\s*$‘)    re_end   = re.compile(r‘^\s*%\s*end(.*?)\s*$‘)    re_code  = re.compile(r‘^\s*%\s*(.*?)\s*$‘)    re_inc   = re.compile(r‘\{\{(.*?)\}\}‘)    def __init__(self, template):        self.code = "\n".join(self.compile(template))        self.co = compile(self.code, ‘<string>‘, ‘exec‘)    def render(self, **args):        ‘‘‘ Returns the rendered template using keyword arguments as local variables. ‘‘‘        args[‘stdout‘] = []        args[‘__builtins__‘] = __builtins__        eval(self.co, {}, args) # 执行Python代码        return ‘‘.join(args[‘stdout‘])    def compile(self, template):        ‘‘‘        将模板转换为可执行的Python代码        ‘‘‘        def code_str(level, line, value):   # 可直接输出的字符串            valuehttp://www.mamicode.com/= "".join(value)            value = http://www.mamicode.com/value.replace("‘","\‘").replace(‘\\‘,‘\\\\‘)            return ‘    ‘*level + "stdout.append(r‘‘‘%s‘‘‘)" % value        def code_print(level, line, value): # {{...}}中的内容,需要执行代码后取得字符串再输出            return ‘    ‘*level + "stdout.append(str(%s)) # Line: %d" % (value.strip(), line)        def code_raw(level, line, value):   # 以%开头,需要作为代码执行            return ‘    ‘*level + value.strip() + ‘ # Line: %d‘ % line        level = 0       # 缩进深度        ln = 0          # 行号(无具体作用,方便定位问题)        sbuffer = []    # 模板中的普通字符串        for line in template.splitlines(True):            ln += 1            # Line with block starting code            m = self.re_block.match(line)            if m:                if sbuffer:                    yield code_str(level, ln, sbuffer)                    sbuffer = []                if m.group(2).strip().lower() in (‘elif‘,‘else‘,‘except‘,‘finally‘):                    if level == 0:                        raise TemplateError(‘Unexpected end of block in line %d‘ % ln)                    level -= 1                yield code_raw(level, ln, m.group(1).strip())                level += 1                continue            # Line with % end marker            m = self.re_end.match(line)            if m:                if sbuffer:                    yield code_str(level, ln, sbuffer)                    sbuffer = []                if level == 0:                    raise TemplateError(‘Unexpected end of block in line %d‘ % ln)                level -= 1                continue            # Line with % marker            m = self.re_code.match(line)            if m:                yield code_raw(level, ln, m.group(1).strip())                continue            # Line with inline code            lasts = 0            for m in self.re_inc.finditer(line):                sbuffer.append(line[lasts:m.start(0)])                yield code_str(level, ln, sbuffer)                sbuffer = []                lasts = m.end(0)                yield code_print(level, ln, m.group(1))            if lasts:                sbuffer.append(line[lasts:])                continue            # Stupid line            sbuffer.append(line)        if sbuffer:            yield code_str(level, ln, sbuffer)if __name__ == "__main__":    # 简单替换    t1 = SimpleTemplate(‘Hello {{name}}!‘)    print t1.render(name=‘<b>World</b>‘)    # 嵌入python语句(必须返回str)    t2 = SimpleTemplate(‘Hello {{name.title() if name else "stranger"}}!‘)    print t2.render(name=None)    print t2.render(name="tuzkee")    # %执行Python语句    tmp3="""%if name:  Hi <b>{{name}}</b>%else:  <i>Hello stranger</i>%end"""    t3 = SimpleTemplate(tmp3)    print t3.render(name=None)    tmp4="""%for i in range(3):%for j in range(3):    {{"%s:%s"%(i,j)}}%end%end"""    t4 = SimpleTemplate(tmp4)    print t4.render()

 

bottle.py中的SimpleTemplate