模板语法有点像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写自定义模板的更多相关文章

  1. [Python自学] day-21 (1) (请求信息、html模板继承与导入、自定义模板函数、自定义分页)

    一.路由映射的参数 1.映射的一般使用 在app/urls.py中,我们定义URL与视图函数之间的映射: from django.contrib import admin from django.ur ...

  2. [python][django学习篇][15]博客侧栏--自定义模板标签

    我们的博客侧边栏有四项内容:最新文章.归档.分类和标签云. 这些内容相对比较固定,且在各个页面都会显示,如果像文章列表或者文章详情一样,从视图函数中获取然后传递给模板,则每个页面对应的视图函数里都要写 ...

  3. 【python】Django自定义模板函数

    参考:https://blog.csdn.net/wenyuanhai/article/details/73656761 注意: 1.自定义模板函数的路径必须为APP的templatetags下:ap ...

  4. Django——模板层(template)(模板语法、自定义模板过滤器及标签、模板继承)

    前言:当我们想在页面上给客户端返回一个当前时间,一些初学者可能会很自然的想到用占位符,字符串拼接来达到我们想要的效果,但是这样做会有一个问题,HTML被直接硬编码在 Python代码之中. 1 2 3 ...

  5. django “如何”系列4:如何编写自定义模板标签和过滤器

    django的模板系统自带了一系列的内建标签和过滤器,一般情况下可以满足你的要求,如果觉得需更精准的模板标签或者过滤器,你可以自己编写模板标签和过滤器,然后使用{% load %}标签使用他们. 代码 ...

  6. django自定义模板标签

    # 创建自定义模板标签目录 django_project_name app_name templatetags (创建Python Packge,注意一定要用templatetags这个名字) my_ ...

  7. [py]python写一个通讯录step by step V3.0

    python写一个通讯录step by step V3.0 参考: http://blog.51cto.com/lovelace/1631831 更新功能: 数据库进行数据存入和读取操作 字典配合函数 ...

  8. python---django中模板渲染(csrf令牌使用,自定义模板函数)

    使用终端,可以更方便的去实验,但是没有提示信息: 在项目目录下: D:\MyPython\day23\HelloWorld>python manage.py shell 开始实验: >&g ...

  9. Django 自定义模板标签和过滤器

    1.创建一个模板库 使用模板过滤器的时候,直接把过滤器写在app里,例如:在app里新建一个templatetags的文件夹,这个目录应当和 models.py . views.py 等处于同一层次. ...

随机推荐

  1. 阻止默认行为是配合passive使用

    在使用lighthouse检测pwa应用时,发现提示下面有下面的警告 默认使用passive:true提高滚动性能并减少崩溃,passive即顺从的,是指它顺从浏览器的默认行为.设置该属性的目的主要是 ...

  2. [在读]javascript框架设计

    司徒正美的书,内容我觉得不错,国内的书很少会讲这些.当然也有很多人吐槽它只贴代码没有解释,文笔不够优美啥啥的,我想说,不要在意这些细节,反正是值得买的一本.

  3. Win10新机的安装与配置

    一.快捷键 打开Chrome上次关闭的所有标签页:Ctrl-Shift-T 二.问题解决 1. 右键取得管理员权限 https://www.tenforums.com/tutorials/3841-a ...

  4. [转].NET MVC 分页以及增删查改

    本文转自:http://blog.csdn.net/sust2012/article/details/30761867 . 数据库操作,DAL 层: using System; using Syste ...

  5. P1664 每日打卡心情好

    题目背景 在洛谷中,打卡不只是一个简单的鼠标点击动作,通过每天在洛谷打卡,可以清晰地记录下自己在洛谷学习的足迹.通过每天打卡,来不断地暗示自己:我又在洛谷学习了一天,进而帮助自己培养恒心.耐心.细心. ...

  6. 【学习笔记】深入理解js原型和闭包(9)—— 简述【执行上下文】下

    继续上一篇文章(https://www.cnblogs.com/lauzhishuai/p/10078231.html)的内容. 上一篇我们讲到在全局环境下的代码段中,执行上下文环境中有如何数据: 变 ...

  7. 必看的dockerfile禁忌与建议!

    直接上对照组(看第三个run) test1 FROM centos MAINTAINER ** ​ RUN yum -y update RUN yum -y install wget ​ RUN wg ...

  8. Ajax的项目搭建

    在搭建Ajax项目之前,首先我们的安装nginx,因为Ajax是基于nginx来运行的, 1.安装nginx 和基本的语法 http://nginx.org/ 上面的nginx的官网,下载直接安装就好 ...

  9. cacti支持中文办法

    1.yum groupinstall "chinese support" 2. 登陆Cacti,在主页的左边点击setting,选择paths页(console>>se ...

  10. ASP.NET Web API FilterAttribute假想

    偶然的测试发现API FilterAttribute没用引用只会初始化一次 比如: 如果是 Global Action Filter, 则全局只会初始化一次 针对于不同的Controller级别的Ac ...