Python模板引擎Jinja2(二)

前言

来啦老铁!

今天咱们继续一起来学习Python模板引擎Jinja2的另外2个重要知识点:

  • 宏;

  • 模板继承;

代码已更新至仓库,自行取阅:

1. 宏;

简单的说,宏与代码中方法的封装、前端组件的概念类似,即我们对Jinja2模板中经常使用的页面元素(当然,也可以是复杂的页面片段)进行封装,这样可以方便代码复用,降低代码冗余。同时,支持有入参的宏。

还不够清楚?咱们来实践实践!宏的编写有2种方式:

  • 一种是在模板中直接进行封装;

  • 一种是将代码块封装到独立的宏文件中去;

(可以参考一下我们平时怎么封装方法、函数的)

1). 在模板中直接进行封装:

  • 在模板文件夹中新增jinja2_maro_demo_1.html,织入如下模板代码:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{% macro input(id, type='text', value='') %}
<input type="{{ type }}" id="{{ id }}" value="{{ value|e }}">
{% endmacro %}

Username:<p>{{ input('username',value=user_name) }}</p>
Password:<p>{{ input('password', type='password',value=pass_word) }}</p>
</body>
</html>

  • 这个东西就是宏:
{% macro input(id, type='text', value='') %}
<input type="{{ type }}" id="{{ id }}" value="{{ value|e }}">
{% endmacro %}

这里将一个input框抽成一个宏,入参id,type(带有默认值text),value分别为input html元素的3种属性,这样我们可以根据传递给宏的参数,渲染出含有不同属性的input框,如普通input框,密码input框等。

  • 而这个就是使用宏的示例:

(其中user_name和pass_word是模板的外部入参,由渲染逻辑传入)

Username:<p>{{ input('username',value=user_name) }}</p>
Password:<p>{{ input('password', type='password',value=pass_word) }}</p>
  • 最后写一个渲染逻辑:

(我们给模板传一个user_name为dylanz、pass_word为123的参数)

def create_jinja2_macro_demo_1_html(self):
    env = Environment(loader=PackageLoader('resources', 'templates'))
    template_name = 'jinja2_macro_demo_1.html'
    template = env.get_template(template_name)
    html = template.render(user_name='dylanz', pass_word='123')

    self.write_output_html(template_name, html)
  • 执行渲染逻辑;
  • 渲染完成后,浏览器打开output文件夹下新生成的jinja2_macro_demo_1.html文件
宏示例1
这样我们就完成了一个带入参的宏,被渲染出多个页面元素的示例啦!

不带入参的宏更简单,把参数去掉就好了,如:

{% macro input() %}
<input type="text" id="test" value="">
{% endmacro %}

2). 将代码块封装到独立的宏文件中去;

承接上面的例子,我们将宏写到独立的文件中去,然后在模板文件中引入,最后完成渲染。

  • 新建宏文件;

在模板文件下新建宏文件夹macros文件夹,在文件夹新建宏文件,如:macro_demo.html,在文件中织入宏代码(就是将宏代码搬到macro_demo.html而已):

{% macro input(id, type='text', value='') %}
<input type="{{ type }}" id="{{ id }}" value="{{ value|e }}">
{% endmacro %}
  • 新的模板文件;

新建模板文件jinja2_macro_demo_2.html,织入代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{% from 'macros/macro_demo.html' import input %}

Username:<p>{{ input('username',value=user_name) }}</p>
Password:<p>{{ input('password', type='password',value=pass_word) }}</p>
</body>
</html>
这里关键的一行代码,将宏引入模板文件:
{% from 'macros/macro_demo.html' import input %}
  • 配套的渲染逻辑:
def create_jinja2_macro_demo_2_html(self):
    env = Environment(loader=PackageLoader('resources', 'templates'))
    template_name = 'jinja2_macro_demo_2.html'
    template = env.get_template(template_name)
    html = template.render(user_name='dylanz', pass_word='123')

    self.write_output_html(template_name, html)
  • 执行渲染逻辑;
  • 渲染完成后,浏览器打开output文件夹下新生成的jinja2_macro_demo_2.html文件:
宏示例2

效果跟直接在模板中声明宏、引用宏一样,说明将代码块封装到独立的宏文件中去,然后再在模板中引用的示例正确无误

这里有几个注意点:

a. 宏文件必须在模板文件夹下或模板文件夹下任意文件夹,因此我们是在templates下新建的macros文件夹;

b. 引入宏的方式,不仅只有{% from 'macros/macro_demo.html' import input %} 这种方式,其实import语句的用法跟python中的import类似,可以直接import...as...,也可以from...import...或者from...import...as...;

c. 宏文件中也可以引用其它宏,使用include关键字代码,如:

{% include 'other_macro_1.html' %}
自己的宏代码
{% include 'other_macro_2.html' %}

2. 模板继承;

模板的继承同样提高了模板代码的重复利用性,我们在父模板中预留位置(称之为block),子模板继承后,再对预留的位置进行实现,这样既保留父模板的通用部分,又能对某些模板位置进行定制。

废话不多说,咱直接开整!

我们在templates文件夹下建立2个模板文件parent.html和child.html:
  • parent.html:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div>这被继承的父模板</div>
{% block content %}
<div>这里是预留位置</div>
{% endblock %}

</body>
</html>

其中,这个就是父模板中为字模板预留的位置,<div>这里是预留位置</div>是我们自己随便放的用于标记一下,真实场景中也可以放任意html:

{% block content %}
<div>这里是预留位置</div>
{% endblock %}

(注意:content为block名字,可任意取)

  • child.html:
{% extends "parent.html" %}
{% block content %}
{{ super() }}
<p>
Hi,这是子模板定制的内容
</p>
{% endblock %}
  • 渲染逻辑:
def create_child_html(self):
    env = Environment(loader=PackageLoader('resources', 'templates'))
    template_name = 'child.html'
    template = env.get_template(template_name)
    html = template.render()

    self.write_output_html(template_name, html)
  • 执行渲染逻辑:

展示前介绍几个注意点:

a. 子模板就不用再写完整的模板文件了;

子模板直接继承parent.html,然后往父模板预留的位置写入内容,如本例为:Hi,这是子模板定制的内容

{% block content %}
{{ super() }}
<p>
Hi,这是子模板定制的内容
</p>
{% endblock %}

b. 当使用了{{ super() }},则父模板预留位置内的内容会保留,即<div>这里是预留位置</div>这个会保留:

继承示例1:有{{ super() }}

c. 当未使用{{ super() }},则则父模板预留位置内的内容不保留,即<div>这里是预留位置</div>这个会去除:

继承示例2:无{{ super() }}

d. 如果父模板中,想使用预留位置的内容,则可以像这样,在父模板中添加代码:

<div>
父模板中再次使用预留位置的内容:
{{self.content()}}
</div>
继承示例3:父模板使用预留位置的内容
至此,我们学习实践了Jinja2的2个重要概念,Jinja2学到这里基本就告一段落了,剩下的就交给时间,交给具体使用场景的考验了!

整个不会很难,建议跟着文章动手做,很容易就能理解。

当然笔者也是参考网上的一些文章,如有不足或错误,烦请指正,感谢!

如果本文对您有帮助,麻烦动动手指点点赞?

谢谢!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,117评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,963评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,897评论 0 240
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,805评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,208评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,535评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,797评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,493评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,215评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,477评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,988评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,325评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,971评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,807评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,544评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,455评论 2 266

推荐阅读更多精彩内容