原文链接

背景

最近在项目开发中,需要针对 Jenkins 项目进行配置,Jenkins 的 job 配置采用的是 xml,在维护配置模板的过程中就遇到了问题,因为逐步发现配置灵活性超出了字符串的范畴,本文旨在简单介绍 Python 下模板引擎模块 Jinja2 的使用。

什么是 Jinja2?

Jinja2 是一个 Python 的功能齐全的模板引擎。它有完整的 unicode 支持,一个可选的集成沙箱执行环境,被广泛使用,以 BSD 许可证授权。

以上是官方说明,简单来说,它提供了替换功能(变量替换)和一些强大的特性(控制流、继承等),可以快速生成数据文件,使得业务与数据分离开来,满足一些灵活多变的配置需求。

为什么要使用 Jinja2?

拿 Jenkins 配置来说,如果要实现不同平台、不同项目的配置,有以下几种方案:

  1. 直接进行字符串替换,使用 Python 字符串语法即可
  2. 使用 XML 解析和生成模块,比较简便的是 ElementTree
  3. 使用模板引擎,例如 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,但缺点也很明显如果两个配置节点数目不相同或者里面的字段差别很大,那么就需要使用 template2template3template4等等,因此此方案仅适合配置需求较为简单,字段不是很复杂的场景。

紧接着,开始调研快速生成不同 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 也会自动为你创建一个环境。推荐使用这种方式进行模板配置而不是使用字符串,大多数程序使用一个环境即可。

用法

  1. 创建一个环境:
from jinja2 import Environment, PackageLoader, select_autoescape

# 初始化 jinja 环境
self.__env = Environment(
loader=PackageLoader('模块名称', '模板文件夹'),
autoescape=select_autoescape(['html', 'xml'])
)
  1. 加载一个模板:

    self.__job_template = self.__env.get_template('job_template.xml')
  2. 接下来就是传递一些业务参数了,

    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 支持基本的iffor、宏等语法,这也是它最强大的地方,目前项目中我只用到了判断就够了。用法如下:

{% 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使用简介的更多相关文章

  1. 【 Python】模块学习之Flask模板引擎:jinja2

    原文链接:https://www.cnblogs.com/dachenzi/p/8242713.html 模板的概念 要了解jinja2,那么需要先理解模板的概念.模板在Python的web开发中广泛 ...

  2. 模板引擎Jinja2的基本用法

    Flask提供的模板引擎为Jinja2,易于使用,功能强大.模板仅仅是文本文件,它可以生成任何基于文本的格式(HTML.XML.CSV.LaTex 等等). 它并没有特定的扩展名, .html 或 . ...

  3. 在windows上如何安装python web引擎jinja2

    首先要把你的Python文件夹加到环境变量里头去.假设你的Python文件夹位于C:\Python34,那么你需要打开CMD并输入: SETX PATH "%path%;C:\Python3 ...

  4. Flask,ORM及模板引擎Jinja2

    跨域:http://blog.csdn.net/yannanxiu/article/details/53036508 下载flask_cors包 pip install flask-cors 使用fl ...

  5. Java模板引擎之freemarker简介

  6. PHP实现简易的模板引擎

    PHP实现简易的模板引擎 1.MVC简介 MVC 是一种使用 MVC(Model View Controller 模型-视图-控制器)设计创建 Web 应用程序的模式(详情自己百度): 1. Mode ...

  7. 【SpringBoot】常用Starter介绍和整合模板引擎Freemaker、thymeleaf

    ========7.SpringBoot常用Starter介绍和整合模板引擎Freemaker.thymeleaf ========================= 1.SpringBoot Sta ...

  8. SpringBoot常用Starter介绍和整合模板引擎Freemaker、thymeleaf 4节课

    1.SpringBoot Starter讲解 简介:介绍什么是SpringBoot Starter和主要作用 1.官网地址:https://docs.spring.io/spring-boot/doc ...

  9. Python Flask Jinja2模板引擎

    模板 简介 模板是一个包含响应文本的文件,其中包含用占位变量表示的动态部分,其具体值只在请 求的上下文中才能知道. 渲染 使用真实值替换变量,再返回最终得到的响应字符串,这一过程 称为渲染.为了渲染模 ...

随机推荐

  1. Web标准和骨架

    Web 标准的好处 1.让Web的发展前景更广阔 2.内容能被更广泛的设备访问 3.更容易被搜寻引擎搜索 4.降低网站流量费用 5.使网站更易于维护 6.提高页面浏览速度 Web 标准构成 Web标准 ...

  2. nodejs process uncaughtException

    用过Node一段时间之后,发现那些在事件主循环里碰到的异常会导致Node进程退出.在许多应用场景下,特别是对那些希望永不当机的服务器程序来说,这都是不接受的.uncaughtException事件会提 ...

  3. Foundation框架介绍

    1.Foundation框架介绍 什么是框架? 众多功能\API的集合 框架是由许多类.方法.函数.文档按照一定的逻辑组织起来的集合,以便使研发程序变得更容易,在OS X下的Mac操作系统中大约有80 ...

  4. 一致性协议之ZAB

    前言 一致性协议 包括 Paxos,Raft,2PC,3PC等等,今天我们讲一种协议,ZAB 协议,该协议应该是所有一致性协议中生产环境中应用最多的了.为什么呢?因为他是为 Zookeeper 设计的 ...

  5. 部署YUM仓库 (最近睡眠质量很差,你什么时候搬过来住)

    部署YUM仓库 1.YUM概述 YUM(Yellow dog Updater Modified) 基于RPM包构建的软件更新机制 可以自动解决依赖关系 所有软件由集中的YUM软件仓库提供 2.主备安装 ...

  6. 数组中包含多个对象 按照对象中的时间进行排序 适用与Angular.js、Jquery、微信小程序等

         LiveList.sort(this.compare('StartDate'))   //StartData:需要排序的时间   compare: function (property) { ...

  7. Nacos中服务删除不了,怎么办?

    前两天遇到了一个问题,Nacos 中的永久服务删除不了,折腾了一番,最后还是顺利解决了.以下是原因分析和解决方案,建议先收藏,以备不时之需. 临时实例和持久化实例是 Nacos 1.0.0 中新增了一 ...

  8. Note -「计算几何」模板

      尚未完整测试,务必留意模板 bug! /* Clearink */ #include <cmath> #include <queue> #include <cstdi ...

  9. Welcom to my studyspace! 欢迎来到我的学习空间!

    由于新手,博客才刚开始起步,用于记录我的学习,博客的建设后续需要将其完善 对我的博客进行diy 用于分享我的学习经历,一些笔记,还有一些小小的心得

  10. Python-Flask框架之"图书管理系统"项目,附详解源代码及页面效果截图

    该图书管理系统要实现的功能如下: 1. 可以通过添加窗口添加书籍或作者,如果要添加的作者和书籍已存在于书架上, 则给出相应的提示: 2. 如果要添加的作者存在,而要添加的书籍书架上没有,则将该书籍添加 ...