Python模板引擎Jinja2使用简介
背景
最近在项目开发中,需要针对 Jenkins 项目进行配置,Jenkins 的 job 配置采用的是 xml,在维护配置模板的过程中就遇到了问题,因为逐步发现配置灵活性超出了字符串的范畴,本文旨在简单介绍 Python 下模板引擎模块 Jinja2 的使用。
什么是 Jinja2?
Jinja2 是一个 Python 的功能齐全的模板引擎。它有完整的 unicode 支持,一个可选的集成沙箱执行环境,被广泛使用,以 BSD 许可证授权。
以上是官方说明,简单来说,它提供了替换功能(变量替换)和一些强大的特性(控制流、继承等),可以快速生成数据文件,使得业务与数据分离开来,满足一些灵活多变的配置需求。
为什么要使用 Jinja2?
拿 Jenkins 配置来说,如果要实现不同平台、不同项目的配置,有以下几种方案:
- 直接进行字符串替换,使用 Python 字符串语法即可
- 使用 XML 解析和生成模块,比较简便的是 ElementTree
- 使用模板引擎,例如 Jinja2
起初,我选用的是方案一,特点是简单粗暴,不需要额外的配置,例如,两个项目的 git 仓库配置可以采用如下代码实现:
# 略去不相关代码
template = b"""<configVersion>2</configVersion>
<userRemoteConfigs>
<hudson.plugins.git.UserRemoteConfig>
<url>%(git_url)s</url>
</hudson.plugins.git.UserRemoteConfig>
</userRemoteConfigs>
<branches>
<hudson.plugins.git.BranchSpec>
<name>%(git_branch)s</name>
</hudson.plugins.git.BranchSpec>
</branches>"""
xml = template % {'git_url':self.__git_url, 'git_branch':self.__git_branch}
这样,只需要外部传入地址及分支,即可获得不同的项目配置 xml,但缺点也很明显如果两个配置节点数目不相同或者里面的字段差别很大,那么就需要使用 template2
、template3
、template4
等等,因此此方案仅适合配置需求较为简单,字段不是很复杂的场景。
紧接着,开始调研快速生成不同 xml 数据的方案,找到了 https://stackoverflow.com/questions/1055108/fast-and-easy-way-to-template-xml-files-in-python, 这里提到了两种方案,也就是上述的2、3。
方案2的特点也很明显,可以完整控制 xml 中每个字段和属性,灵活性确实够了,能够满足我们的需求,但是有点大炮打蚊子的感觉,而且频繁的读写 xml 也比较消耗性能,业务逻辑也会随着配置的灵活性和多样性急遽膨胀,比如 Jenkins 项目配置,仓库地址、分支信息、ssh 信息、tag 字段、打包脚本等等,如果使用 xml 解析的话,针对这些节点都必须创建对应的业务逻辑,不是很推荐。
那么我们的选择也比较简单了,Jinja 可以快速的替换生成我们业务需要的各种各样的数据,而且接入成本低,业务逻辑不会变化太大,下面简单介绍下本次项目中的使用。
Jinja2的简单使用教程
安装
这个比较简单,看下文档即可,执行命令
pip install jinja2
基本概念
Jinja2中有一个名为Environment
的对象,用于存储配置、全局变量,并且用于从文件系统中加载模板。即使你通过Template
用字符串创建一个模板,Jinja2 也会自动为你创建一个环境。推荐使用这种方式进行模板配置而不是使用字符串,大多数程序使用一个环境即可。
用法
- 创建一个环境:
from jinja2 import Environment, PackageLoader, select_autoescape
# 初始化 jinja 环境
self.__env = Environment(
loader=PackageLoader('模块名称', '模板文件夹'),
autoescape=select_autoescape(['html', 'xml'])
)
加载一个模板:
self.__job_template = self.__env.get_template('job_template.xml')
接下来就是传递一些业务参数了,
self.__config = self.__job_template.render(
git_url=self.__git_remote_url,
git_branch=self.__git_branch,
git_tag=self.__git_tag
)
以上都还是比较简单的 API 调用,核心使用部分在与如何在模板中通过 Jinja 支持的语法灵活的进行数据配置。
基本变量替换
最基础的功能就是进行变量替换了,语法为{{变量名}}
, 例如将 url 传递到 xml 中,模板中写法为(省略了不相关内容):
<userRemoteConfigs>
<hudson.plugins.git.UserRemoteConfig>
<url>{{git_url}}</url>
</hudson.plugins.git.UserRemoteConfig>
</userRemoteConfigs>
然后在代码中向上面一样调用 template.render(git_url='xxx')
即可
控制流
Jinja 支持基本的if
、for
、宏等语法,这也是它最强大的地方,目前项目中我只用到了判断就够了。用法如下:
{% if push_tag %}
<tagsToPush>
<hudson.plugins.git.GitPublisher_-TagToPush>
<targetRepoName>origin</targetRepoName>
<tagName>{{git_tag}}</tagName>
<tagMessage></tagMessage>
<createTag>true</createTag>
<updateTag>true</updateTag>
</hudson.plugins.git.GitPublisher_-TagToPush>
</tagsToPush>
{% endif %}
上面这段 xml 的逻辑就是如果传入了 push_tag
变量且为True
则在 Jenkins 配置中增加推送 git tag 节点,否则不做任何处理。
除此之外,Jinja2 还支持循环,
<dl>
{% for key, value in my_dict.iteritems() %}
<dt>{{ key|e }}</dt>
<dd>{{ value|e }}</dd>
{% endfor %}
</dl>
详细说明可以参考 http://docs.jinkan.org/docs/jinja2/templates.html#for
继承
这部分由于目前项目配置还比较简单,暂时没用到,可以参考 http://docs.jinkan.org/docs/jinja2/templates.html#id23
结语
对于简单的项目来说,上面提到的一些基本替换加控制流基本都能满足使用了, 稍微复杂一点的程序可以考虑使用继承和扩展。
总的来说,Jinja2 既强大又简便,完美符合项目中一些HTML、XML 的业务配置需求,目前项目中本身有的三四个 xml 文件用了 Jinja2 之后缩减成一个,同时改动工作量大约只花了几个小时,真的很方便。
参考资料:
Python模板引擎Jinja2使用简介的更多相关文章
- 【 Python】模块学习之Flask模板引擎:jinja2
原文链接:https://www.cnblogs.com/dachenzi/p/8242713.html 模板的概念 要了解jinja2,那么需要先理解模板的概念.模板在Python的web开发中广泛 ...
- 模板引擎Jinja2的基本用法
Flask提供的模板引擎为Jinja2,易于使用,功能强大.模板仅仅是文本文件,它可以生成任何基于文本的格式(HTML.XML.CSV.LaTex 等等). 它并没有特定的扩展名, .html 或 . ...
- 在windows上如何安装python web引擎jinja2
首先要把你的Python文件夹加到环境变量里头去.假设你的Python文件夹位于C:\Python34,那么你需要打开CMD并输入: SETX PATH "%path%;C:\Python3 ...
- Flask,ORM及模板引擎Jinja2
跨域:http://blog.csdn.net/yannanxiu/article/details/53036508 下载flask_cors包 pip install flask-cors 使用fl ...
- Java模板引擎之freemarker简介
- PHP实现简易的模板引擎
PHP实现简易的模板引擎 1.MVC简介 MVC 是一种使用 MVC(Model View Controller 模型-视图-控制器)设计创建 Web 应用程序的模式(详情自己百度): 1. Mode ...
- 【SpringBoot】常用Starter介绍和整合模板引擎Freemaker、thymeleaf
========7.SpringBoot常用Starter介绍和整合模板引擎Freemaker.thymeleaf ========================= 1.SpringBoot Sta ...
- SpringBoot常用Starter介绍和整合模板引擎Freemaker、thymeleaf 4节课
1.SpringBoot Starter讲解 简介:介绍什么是SpringBoot Starter和主要作用 1.官网地址:https://docs.spring.io/spring-boot/doc ...
- Python Flask Jinja2模板引擎
模板 简介 模板是一个包含响应文本的文件,其中包含用占位变量表示的动态部分,其具体值只在请 求的上下文中才能知道. 渲染 使用真实值替换变量,再返回最终得到的响应字符串,这一过程 称为渲染.为了渲染模 ...
随机推荐
- onerror事件捕获网页中的错误
转载请注明来源:https://www.cnblogs.com/hookjc/ <html><head><script type="text/javascrip ...
- Ajax使用post方式发送数据注意事项
Ajax使用post方式给服务器传递数据时,需要将传递的字符串转化为模拟from表单发送数据的XML格式 在open之后奢姿头协议信息,模拟from表单传递数据 xhr.setRequestHeade ...
- OSChina 文
转载请注明来源:https://www.cnblogs.com/hookjc/ http://www.oschina.net/p/carbon-forum [高性能PHP论坛 Carbon For ...
- C语言中的typedef跟define的区别
今天用C语言练习时涉及到了typedef和define的使用问题,那么他们的区别是啥?这种情况下为什么要用typedef?哪种情况下为什么要用define呢? 学习C的时候的你是否考虑过这个问题呢? ...
- Java基础复习(六)
1. 接口的实现类中的实现接口中的抽象方法的方法必须为public,为什么? 接口中所有的方法与变量都默认是 public 的,在接口中可以不写出来.但在实现类中,如果不明写的话,就变成了 frien ...
- kubeadm部署安装+dashboard+harbor
kubeadm 部署安装+dashboard+harbor master(2C/4G,cpu核心数要求大于2) 192.168.80.10 docker.kubeadm.kubelet.kubectl ...
- Ubuntu service 命令
启动指定服务 sudo service 服务名 start 停止指定服务 sudo service 服务名 stop 重启指定服务 sudo service 服务名 start 查看所有服务 sudo ...
- pm2 部署 vue
链接:我整理了一个网站, 用来介绍一些有意思和实用工具的网站, 我没有打包, 直接甩上去了 因为vue是用 npm run dev 来运行的, 你用pm2 npm run dev 是错误的 需要加上- ...
- 面向过程编程+模块&导入
面向过程编程+模块&导入 一.面向过程编程(理论+简单代码) 面向过程编程就好比在设计一条产品流水线 首先我们来认识下,什么是面向过程?如果咬文嚼字的话可以这样来理解,面向过程就是面向解决问题 ...
- Solution -「NOI 2012」「洛谷 P2050」美食节
\(\mathcal{Description}\) Link. 美食节提供 \(n\) 种菜品,第 \(i\) 种的需求量是 \(p_i\),菜品由 \(m\) 个厨师负责制作,第 \(j\) ...