模板语法有点像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. 目标&计划

    目标 感觉起来NOIP还是能考到一个比较好的分数的吧 550+? 现在可能还不大行,但是过3个月或许还是能考到的 所以先订下NOIP保底500争取550+吧 至于省选... 前面有一群巨佬挡着,感觉想 ...

  2. [BJOI2017]魔法咒语

    Description Chandra 是一个魔法天才. 从一岁时接受火之教会洗礼之后, Chandra 就显示出对火元素无与伦比的亲和力,轻而易举地学会种种晦涩难解的法术.这也多亏 Chandra ...

  3. 线段树(区间合并) HDOJ 3308 LCIS

    题目传送门 题意:线段树操作:1. 单点更新 2. 求区间的LCIS(longest consecutive increasing subsequence) 分析:注意是连续的子序列,就是简单的区间合 ...

  4. Java项目的命名规则

    Java类的命名规范如下: 1. 项目名全部小写 2. 包名全部小写 3. 类名首字母大写,如果类名由多个单词组成,每个单词的首字母都要大写. 如:public class MyFirstClass{ ...

  5. Python 3.6.5安装过程中小错误zipimport.ZipImportError: can't decompress data; zlib not available

    执行 :yum install -y zlib*之后,就好了.该安装错误是在CentOS7.4中遇到的.

  6. NFS与AutoNFS实例

    NFS概述: NFS,是Network File System的简写,即网络文件系统.网络文件系统是FreeBSD支持的文件系统中的一种,也被称为NFS. NFS允许一个系统在网络上与他人共享目录和文 ...

  7. K-means算法Java实现

    public class KMeansCluster {          private int k;//簇的个数          private int num = 100000;//迭代次数  ...

  8. MATLAB学习总结(1)

    MATLAB学习总结(1)   path help path cd(current directory) savepath pathtool

  9. 【HEVC帧间预测论文】P1.7 Content Based Hierarchical Fast Coding Unit Decision Algorithm

    Content Based Hierarchical Fast Coding Unit Decision Algorithm For HEVC <HEVC标准介绍.HEVC帧间预测论文笔记> ...

  10. centos开机直接进入命令行

    找到文件,/etc/inittab 文件,在下面有一行 id:5:initdefault: 将上面的5改成3就可以了 5是图形界面 3是命令行界面 就是文本界面.