用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_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写自定义模板的更多相关文章
- [Python自学] day-21 (1) (请求信息、html模板继承与导入、自定义模板函数、自定义分页)
一.路由映射的参数 1.映射的一般使用 在app/urls.py中,我们定义URL与视图函数之间的映射: from django.contrib import admin from django.ur ...
- [python][django学习篇][15]博客侧栏--自定义模板标签
我们的博客侧边栏有四项内容:最新文章.归档.分类和标签云. 这些内容相对比较固定,且在各个页面都会显示,如果像文章列表或者文章详情一样,从视图函数中获取然后传递给模板,则每个页面对应的视图函数里都要写 ...
- 【python】Django自定义模板函数
参考:https://blog.csdn.net/wenyuanhai/article/details/73656761 注意: 1.自定义模板函数的路径必须为APP的templatetags下:ap ...
- Django——模板层(template)(模板语法、自定义模板过滤器及标签、模板继承)
前言:当我们想在页面上给客户端返回一个当前时间,一些初学者可能会很自然的想到用占位符,字符串拼接来达到我们想要的效果,但是这样做会有一个问题,HTML被直接硬编码在 Python代码之中. 1 2 3 ...
- django “如何”系列4:如何编写自定义模板标签和过滤器
django的模板系统自带了一系列的内建标签和过滤器,一般情况下可以满足你的要求,如果觉得需更精准的模板标签或者过滤器,你可以自己编写模板标签和过滤器,然后使用{% load %}标签使用他们. 代码 ...
- django自定义模板标签
# 创建自定义模板标签目录 django_project_name app_name templatetags (创建Python Packge,注意一定要用templatetags这个名字) my_ ...
- [py]python写一个通讯录step by step V3.0
python写一个通讯录step by step V3.0 参考: http://blog.51cto.com/lovelace/1631831 更新功能: 数据库进行数据存入和读取操作 字典配合函数 ...
- python---django中模板渲染(csrf令牌使用,自定义模板函数)
使用终端,可以更方便的去实验,但是没有提示信息: 在项目目录下: D:\MyPython\day23\HelloWorld>python manage.py shell 开始实验: >&g ...
- Django 自定义模板标签和过滤器
1.创建一个模板库 使用模板过滤器的时候,直接把过滤器写在app里,例如:在app里新建一个templatetags的文件夹,这个目录应当和 models.py . views.py 等处于同一层次. ...
随机推荐
- Codeforces Round #325 (Div. 2)
水 A - Alena's Schedule /************************************************ * Author :Running_Time * Cr ...
- 树状数组+二分||线段树 HDOJ 5493 Queue
题目传送门 题意:已知每个人的独一无二的身高以及排在他前面或者后面比他高的人数,问身高字典序最小的排法 分析:首先对身高从矮到高排序,那么可以知道每个人有多少人的身高比他高,那么取较小值(k[i], ...
- 18.3.1获得Class对象
package d18_3_1; /** * Java中的java.lang.Class,简单理解就是为每个java对象的类型标识的类, * 虚拟机使用运行时类型信息选择正确的执行方法,用来保存这些运 ...
- SpringMVC之基于注解的Controller
参考博客:https://www.cnblogs.com/qq78292959/p/3760560.html Controller注解: 传统风格的Controller需要实现Controller接口 ...
- Vue nextTick 理解
官网解释: 将回调延迟到下次 DOM 更新循环之后执行.在修改数据之后立即使用它,然后等待 DOM 更新.它跟全局方法 Vue.nextTick 一样,不同的是回调的 this 自动绑定到调用它的实例 ...
- Java GC机制简要总结(Java垃圾回收的基本工作原理)
第一次编辑 2019-05-07 01:09:39 垃圾回收的对象 程序中的不可用对象(不存活的对象,没有任何引用),或者无用的变量信息等,在程序中长期存在会逐渐占用较多的内存空间,导致没有足够的空间 ...
- UVA 11971 Polygon 多边形(连续概率)
题意: 一根长度为n的木条,随机选k个位置将其切成k+1段,问这k+1段能组成k+1条边的多边形的概率? 思路: 数学题.要求的是概率,明显与n无关. 将木条围成一个圆后再开切k+1刀,得到k+1段. ...
- 基于SAE的Python+Django部署
本文主要参考:http://www.cnblogs.com/qtsharp/archive/2012/01/12/2320774.html,另外包括自己的实际操作. 一.申请SAE帐号以及创建应用ya ...
- 在.vue文件中让html代码自动补全的方法(支持vscode)
在.vue文件中让html代码自动补全的方法(支持vscode) https://blog.csdn.net/qq_36529459/article/details/79196763 "fi ...
- 部署 k8s Cluster(下)【转】
上节我们通过 kubeadm 在 k8s-master 上部署了 Kubernetes,本节安装 Pod 网络并添加 k8s-node1 和 k8s-node2,完成集群部署. 安装 Pod 网络 要 ...