《The-Flask-Mega-Tutorial》学习笔记02--模板

46 阅读2分钟

学习地址:The-Flask-Mega-Tutorial-zh/docs/第二章:模板.md

模板有助于实现页面展现和业务逻辑之间的分离。 在Flask中,模板被编写为单独的文件,存储在应用程序包内的templates文件夹中。

模板体验

image.png

# views.py
from app_name import app
from flask import render_template


@app.route('/')
@app.route('/index')
def index():
    user = {'username': 'Miguel'}
    return render_template('index.html', title='Home', user=user)
# index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{ title }}</title>
</head>
<body>
    <h1>Hello, {{ user.username }} !</h1>
</body>
</html>

image.png

Jinja2模板引擎

image.png 将模板转换为完整的HTML页面的操作称为渲染。 为了渲染模板,需要从Flask框架中导入一个名为render_template()的函数。 render_template()函数调用Flask框架原生依赖的Jinja2模板引擎(点击链接自己研究)。

常见模板语句块

1、{{ ... }}

  • 定义变量
{{ <变量名> }}
  • for循环中的特殊变量(获取当前遍历状态) image.png 例如:
{% for item in items %}
  <li>{{ loop.index0 }}: {{ <变量名> }}</li>
{% endfor %}
  • 自定义全局变量(代码中定义,模板中使用)
from jinja2 import Environment

# 定义全局变量
my_var = 'Hello, world!'

# 创建模板引擎
env = Environment()

# 添加全局变量
env.globals['my_var'] = my_var

# 渲染模板
template = env.from_string('<p>{{ my_var }}</p>')
result = template.render()
print(result)

2、{% ... %}

  • 条件语句(if...else)
{% if <条件表达式> %}
... html ...
{% else %}
... html ...
{% endif %}
  • 循环语句(for...)
{% for <条件表达式> %}
... html ...
{% endfor %}
  • 继承语句
# 基础模板base.html
... html ...
{% block <content_name> %}
{% endblock %}

# 继承模板index.html
{% extends "base.html" %}

{% block <content_name> %}
... new html ...
{% endblock %}
  • 包含语句
{% include "xxx.html" %}

模板的继承

可以将所有模板中相同的部分转移到一个基础模板中,然后再从基础模板继承过来,这就是模板的继承特性。

举例说明继承:

  1. 新建一个基础模板:base.html
<html>
    <head>
      {% if title %}
      <title>{{ title }} - Microblog</title>
      {% else %}
      <title>Welcome to Microblog</title>
      {% endif %}
    </head>
    <body>
        <div>Microblog: <a href="/index">Home</a></div>
        <hr>
        {% block content %}{% endblock %}
    </body>
</html>
  1. 新建一个继承模板: index.html
{% extends "base.html" %}

{% block content1 %}
    <h1>Hi, {{ user.username }}!</h1>
    {% for post in posts %}
    <div><p>{{ post.author.username }} says: <b>{{ post.body }}</b></p></div>
    {% endfor %}
{% endblock %}
  • extends语句用来建立了两个模板之间的继承关系;
  • block语句让Jinja2知道如何将这两个模板合并成在一起;
  • content是名称,可以自定义;

模板的包含

可以将重复的代码抽象为一个单独的模板,然后在其他模板中引用它,避免重复的代码和布局。

例如:定义一个头部模板 header.html,它包含了网站的标题和导航菜单。然后在页面模板 page.html 中引用头部模板。

<!-- header.html -->
<header>
  <h1>My Website</h1>
  <nav>
    <ul>
      <li><a href="/">Home</a></li>
      <li><a href="/about">About</a></li>
      <li><a href="/contact">Contact</a></li>
    </ul>
  </nav>
</header>

<!-- page.html -->
{% include "header.html" %}

<main>
  <h1>Welcome to my page!</h1>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</main>

总结&拓展