当前位置:   article > 正文

Flask模板引擎——Jinja2

Flask模板引擎——Jinja2

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

1. 渲染模板

默认情况下,Flask在程序文件夹中的templates子文件夹中寻找模板。

from flask import Flask, render_template

    app = Flask(__name__)

    @app.route('/')
    def index():
        return render_template('index.html')

    @app.route('/user/<name>')
    def user(name):
        return render_template('user.html', name=name)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

render_template 函数的第一个参数是模板的文件名(index.html,user.html),随后的参数都是键值对(name=name),表示模板中变量的真实值。

2. 变量

template/user.html:Jinja2模板

<h1>Hello,{{ name }}!<h1>
  • 1

{{ name }}结构表示一个变量,告诉模板引擎这个位置的值从渲染模板时使用的数据中获取。
可以使用过滤器修改变量,过滤器名称添加在变量名之后,中间使用竖线分割。

Hello,{{ name|capitalize }}
  • 1

Jinja2变量过滤器:
safe: 渲染时不转义
capitalize:把值的首字母转换成大写,其他字母转换成小写
lower: 把值转换成小写形式
upper: 把值转换成大写形式
title: 把值中每个单词的首字母都转换成大写
trim: 把值的首尾空格都去掉
striptags: 渲染之前把值中所有的HTML标签都删掉

3.控制结构

if循环

例:

{%if user %}
    Hello, {{ user }}!
{% else %}
    Hello, Stranger!
{% endif %}
  • 1
  • 2
  • 3
  • 4
  • 5

for循环

<ul>
    {% for comment in comments %}
        <li>{{ comment }}<li>
    {% endfor %}
</ul>
  • 1
  • 2
  • 3
  • 4
  • 5

宏类似于函数。需要在多处重复使用的模板代码片段可以写入单独的文件,再包含在所有模板中,以避免重复。另一种重复使用代码的强大方式是模板继承。
例:
首先创建一个名为base.html的基模板。

<html>
<head>
    {% block head %}
    <title>{% block title %}{% endblock %} - My Application</titel>
    {% endblock %}
</head>
<body>
    {% block body %}
    {% endblock %}
</body>
<html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

由block标签定义的元素可以在衍生模板中修改。head,title,body,注意title包含在head中
下面示例是基模板的衍生模板。

{% extends "base.html" %}
{% block title %}index{% endblock %}
{% block head %}
    {{ super }}
    <style>
    </style>
{% endblock %}
{% block body %}
<h1>Hello, World!</h1>
{% endblock %}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

extends指令声明这个模板衍生自base.html。基模板中的三个块被重新定义,模板引擎会将其插入适当的位置。**注意新定义的head块,在基模板中其内容不是空的,所以使用super()获取原来的内容。

4.自定义错误页面

最常见的错误代码有两个:404,客户端请求未知页面或路由时显示;500,有未处理的异常时显示。
示例:自定义错误页面

@app.errorhandler(404)
def page_not_found(e):
    return render_template('404.html'), 404


@app.errorhandler(500)
def internal_server_error(e):
    return render_template('500.html'), 500
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

错误处理程序中引用的模板也需要编写。这些模板应该和常规页面使用相同的布局,因此要有一个导航条和显示错误消息的页面头部。
Flask-Bootstrap提供了一个具有页面基本布局的基模板。
示例:

{% extends "bootstrap/base.html" %}

{% block title %}Flasky{% endblock %}

{% block navbar %}
<div class="navbar navbar-inverse" role="navigation">
    <div class="container">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="/">Flasky</a>
        </div>
        <div class="navbar-collapse collapse">
            <ul class="nav navbar-nav">
                <li><a href="/">Home</a></li>
            </ul>
        </div>
    </div>
</div>
{% endblock %}

{% block content %}
<div class="container">
    {% block page_content %}{% endblock %}
</div>
{% endblock %}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

这是一个继承自bootstrap/base.html的新模板,其中定义了导航条。content块中只有个div容器,其中包含了一个名为page_content的新的空块,块中的内容由衍生模板定义。
通过继承base.html模板写404.html。示例:

{% extends "base.html" %}

{% block title %}Flasky - Page Not Found{% endblock %}

{% block page_content %}
<div class="page-header">
    <h1>Not Found</h1>
</div>
{% endblock %}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

505.html:

{% extends "base.html" %}

{% block title %}Flasky - Internal Server Error{% endblock %}

{% block page_content %}
<div class="page-header">
    <h1>Internal Server Error</h1>
</div>
{% endblock %}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

user.html:

{% extends "base.html" %}

{% block title %}Flasky{% endblock %}

{% block page_content %}
<div class="page-header">
    <h1>Hello, {{ name }}!</h1>
</div>
{% endblock %}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

5.链接

Flask提供了url_for()辅助函数,它可以使用程序URL映射中保存的信息生成URL。
使用url_for()生成动态地址时,将动态部分作为关键字参数传入。例如:url_for(‘user’, name = ‘john’, _external = True)的返回结果时http://localhost:5000/user/john.
传入url_for()的关键字参数不仅限于动态路由中的参数。函数能将任何额为参数添加到查询字符中。

6.静态文件

默认设置下,Flask在程序根目录中名为static的子目录中寻找静态文件。
示例展示了如何在程序的基模板中放置favicon.ico图标(此图标就是Flask的logo)。这个图标会显示在浏览器的地址栏中。
示例:

...
{% block head %}
{{ super() }}
<link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}" type="image/x-icon">
<link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}" type="image/x-icon">
{% endblock %}
...
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

图标的声明会插入head块的末尾。使用super()保留基模板中定义的块的原始内容。

7.使用Flask-Moment本地化日期和时间

Flask-Moments时一个Flask扩展,用于把moment.js集成到jinjia2模板中。
引入moment.js库(在base.html模板底部):

...
{% block scripts %}
{{ super() }}
{{ moment.include_moment() }}
{% endblock %}
  • 1
  • 2
  • 3
  • 4
  • 5

在hello.py中加入一个datetime变量:

...
from datetime import datetime
...
moment = Moment(app)
...
@app.route('/')
def index():
    return render_template('index.html',
                           current_time=datetime.utcnow())
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

使用Flask-Moment渲染时间戳(在index.html中加入):

...
<p>The local date and time is {{ moment(current_time).format('LLL') }}.</p>
<p>That was {{ moment(current_time).fromNow(refresh=True) }}.</p>
  • 1
  • 2
  • 3
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/在线问答5/article/detail/769092
推荐阅读
相关标签
  

闽ICP备14008679号