flask二、Template模版引擎(Jinja2)

Flask Template模版引擎(Jinja2)

Flask利用Jinja2作为模版引擎。模版引擎包含了变量和表达式,当模版被渲染时,它们被替换为值和标签,它们控制着模版的逻辑。

Jinja2默认的几种分割符:

  • {% ... %} 表示声明
  • {{ ... }} 表达式打印到模版输出
  • {# ... #} 对于未包含在模板输出中的注释
  • # ... ## 行语句

变量

传递给模版的上下文字典定义了模版的变量

通过{{ ... }}在模版中打印变量

{{ foo.bar }}
{{ foo['bar'] }}

双花括号不是变量的一部分,而是打印语句。如果访问标签内的变量,在双花括号周围不要再次出现大括号。

如果变量或属性不存在,将会返回一个未定义的值,默认的行为是打印或迭代计算为空字符串,并且每次操作都会失败。
在Flask中如果需要加载静态文件的URL,有两种实现的方法:

<link rel='stylesheel' href='/static/css/style.css'>
<link rel='stylesheel' href='{{ url_for('static', filename='css/style.css') }}'>

过滤器

变量可以通过过滤器进行修改。过滤器通过管道符合(|)与变量分开,并且可以在括号中包含可选参数。可以链接多个过滤器。一个过滤器的输出应用于下一个过滤器。

例如{{ name | striptags | length }}从name变量中移除所有的HTML标签,并计算长度进行打印输出。

接受参数的过滤器在参数周围有括号,就像函数调用一样。例如:{{ listx | join (',') }}将以逗号为间隔将列表进行打印输出,与Python的str.join(',', listx)相似。

转义

有时需要或必要让Jinja2忽略它会以变量或块的形式处理的部分。例如,如果使用迷人语法,你希望使用{{作为模版中的原始字符串并且不启动变量。

{{ '{{' }}

对于更大的部分,将原始块标记为块是有意义的,使用{% raw %}。例如,要在模版中包含示例Jinja语法,且不执行代码。

{% raw %}
    <ul>
    {% for item in seq %}
        <li>{{ item }}</li>
    {% endfor %}
    </ul>
{% endraw %}

基本模版

通常会创建一个base.html模版,它定义了一个简单的HTML骨架文档,你可以将它用于简单的三段式页面。让孩子模版来完成空白块内容的填充工作。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">

    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
    <title>{% block title %}{% endblock %}</title>
    {% block extCSS %}
        <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
    {% endblock %}
</head>
<body>
{% block header %}

{% endblock %}

{% block content %}

{% endblock %}

{% block footer %}

{% endblock %}
</body>
</html>

在本例中,{% block %} 标签定义了五个可以填充子模版的块,所有块标签都会告诉模板引擎,子模板可能会覆盖模板中的占位符。

子模板

下面介绍下子模版中的示例:

{% extends 'base.html' %}
{% block title %}Index{% endblock %}
{% block extCSS %}
    {{ super() }}
    <style>
        .test{color: red;}
    </style>
{% endblock %}
{% block header %}<p>header</p>{% endblock %}
{% block content %}<p>content</p>{% endblock %}
{% block footer %}<p>footer</p>{% endblock %}

{% extends %}标签是这里的关键。它告诉模版引擎该模板‘扩展’了另一个模板。当模版系统读取这个模板时,它会首先找到父模板。扩展标签应该是模板中的第一个标签。

通过{{ super() }} 来渲染父模块的内容。这将返回父模块的结果。

结构控制语句

控制结构是指所有那些控制程序流程的东西-条件(if/elif/else), for循环,以及宏和块。使用默认语法,控制结构出现在{% ... %}块内。

For

循环顺序中的每个项目。例如,显示一个名为users的变量中提供的用户列表。

<h1>User List</h1>
<ul>
{% for user in users %}
    <li>user.username</li>
{% endfor %}
</ul>

由于模板中的变量保留了它们的对象属性,因此可以像dict一样遍历容器:

<dl>
{% for key, value in my_dict.iteritems() %}
    <dt>{{ key }}</dt>
    <dd>{{ value }}</dd>
{% endfor %}
</dl>

在for循环块的内部, 可以访问一些特殊变量

描述
loop.index 循环的当前迭代(1开始)
loop.index0 循环的当前迭代(0开始)
loop.revindex 循环倒叙的迭代(到1结束)
loop.revindex0 循环倒叙的迭代(到0结束)
loop.first 如果第一次迭代,则为真
loop.last 如果最后次迭代, 则为真
loop.length 序列中的项目数量。
loop.cycle 在一系列序列之间循环的辅助函数。
loop.depth 指示当前呈现的递归循环中有多深。从1开始
loop.depth0 指示当前呈现的递归循环中有多深。从0开始
loop.previtem 来自上一次循环迭代的项目。在第一次迭代期间未定义。
loop.nextitem 来自下一次循环迭代的项目。在最后一次迭代期间未定义。
loop.changed(*val) 如果以前用不同的值调用(或根本不调用),则为真。

IF

与Python中的if语句相当。用最简单的形式,你可以用它来测试一个变量是否被定义,不是空的和不是false

{% if users %}
<ul>
{% for user in users %}
    <li>{{ user.username }}</li>
{% endfor %}
</ul>
{% endif %}

对于多个分支,elif和else可以像在Python中一样使用, 也可以使用更复杂的表达式。

{% if age < 18 %}
    你还未成年
{% elif age == 18 %}
    刚好成年
{% else %}
    你已经不小了
{% endif %}

Macros

宏与常规编程语言中的函数具有可比性。将常用惯用语放入可重复使用的函数中,以便不重复干同样的事情。

{% macro input(name, value='', type='text', size=20) -%}
    <input type="{{ type }}" name="{{ name }}" value="{{
        value|e }}" size="{{ size }}">
{%- endmacro %}

宏可以被当做一个函数调用:

<div>{{ input('username') }}</div>
<div>{{ input('password', type='password') }}</div>

Blocks

块用于继承,同时用作占位符和替换。它们在“模板继承”部分详细记录。

Include

include语句对于包含模板并将该文件的渲染内容返回到当前名称空间非常有用:

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

推荐阅读更多精彩内容