Day 16 Flask 前端

本来前端应该要更早点讲的,不过 Flask 的前端有了传入的值的话,可以有更多的操作,所以就放到这边才讲了。

Flask 的前端是由 Jinja2 样版引擎来处理,而样板引擎可以像是程序语言一样对参数进行各种处里。

後端

首先,前端的页面预设是放在专案根目录下的 templates (有 s,可以改位置,但下一篇静态档案时再说),就像这样:

ithome/
├── templates
│   └── index.html
├── app.py
├── configs.py
├── Pipfile
└── Pipfile.lock

既然这篇主题是前端,那麽先把跟主题无关的後端部分快速讲完。後端要传回页面是使用 render_template() 这个 function,这个 function 第一个参数必须是一个页面的档案;後面跟着要传入页面的参数,使用 key-value 传入,value 可以是 dict 、 list 或一般的变数。就像这样:

app.py

@app.route('/')
def index():
    return render_template('index.html')
    # or
    return render_template('index.html', username='<username>')
    # or
    return render_template('index.html', username=['A', 'B', 'C'])
    # or
    return render_template('index.html', username={'Users': ['A', 'B', 'C'])

後端要传回页面大概可以用这几种方式,不一定只能有一个 key-value ,也可以有多个(中间皆使用逗点分开)。

前端

接着就要来说道前端页面的部份了,刚刚讲到样板引擎可以像程序语言一样对参数进行处理,甚至进行各种条件判断。说到这些,想当然的一定有 if-else 跟 for 了吧。

Jinja2 样板引擎可以处里 .html 档(虽然可以处里的不只 .html 就是了),在 Jinja2 除了可以解析普通的 HTML 语法,还有两种特殊的标签:{{ }}{% %}{{ }} 是使用在渲染到页面上的标签;{% %} 是使用在各种判断以及回圈使用的标签。需要注意的大概就这样而已,接着实际操作一次会更加清晰。

if-elif-else

第一个是最常用的 if-elif-else,实际来看一下前後端如何实作吧:

app.py

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

@app.route('/<username>')
def user_home(username):
    return render_template('index.html', username=escape(username))

index.html

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8" />
    <title>template value</title>
</head>

<body>
    <div>
        {% if username %}
            <h1>Welcome {{ username }}</h1>
        {% else %}
            <h1>Hello</h1>
        {% endif %}
    </div>
</body>

</html>

这样就可以再有输入使用者名称的时候,会自动显示出不同的页面。像这样:

http://localhost:5000/

http://localhost:5000/User

for

第二个也是很常使用的 for,这边也直接来看如何实作吧:

app.py

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

@app.route('/<username>')
def user_home(username):
    return render_template('index.html', username=escape(username))


@app.route('/<int:time>')
def user_list_home(time):  # 真的不知道要取什麽名字了
    users = []
    for i in range(time):
        users.append("user" + str(i))

    return render_template('index.html', users=users)

index.html

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8" />
    <title>template value</title>
</head>

<body>
    <div>
        {% if username %}
            <h1>Welcome {{ username }}</h1>
        {% elif users %}
            {% for username in users %}
                <h1>Welcome {{ username }}</h1>
            {% endfor %}
        {% else %}
            <h1>Hello</h1>
        {% endif %}
    </div>
</body>

</html>

基本上只是根据前一个小改而已,所以输入前面那两个 URL 也会出现一样的结果,不一样的只有这个:

http://localhost:5000/5

常用的逻辑控制大概就这样,接着要讲不太一样的东西。

extends & block

如果现在要做多个画面,四周都差不多,只有中间内容不太一样(就像这篇跟上一篇一样,只有中间内容不一样),这时有两个方法可以解决。第一个想到的就是万能的 ctrl + c & ctrl + v 对吧,真的很好用我知道,但是有点太慢了。第二个就是这个 extendsblock

那这个要怎麽用呢?让我们先打架构改成这样,再根据上面的程序小改一下。

ithome
├── templates
│   ├── res  # 先随便取个名字,不用做资料夹也行。
│   │   └── home.html  # 它跟 base.html 同一层也可以
│   ├── base.html
│   └── index.html
├── app.py
├── configs.py
├── Pipfile
└── Pipfile.lock

app.py

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

@app.route('/<username>')
def user_home(username):
    return render_template('res/home.html', username=escape(username))


@app.route('/<int:time>')
def user_list_home(time):  # 真的不知道要取什麽名字了
    users = []
    for i in range(time):
        users.append("user" + str(i))

    return render_template('res/home.html', users=users)

base.html

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8" />
    <title>{% block title %}{% endblock %}</title>
</head>

<body>
    <div>
        {% block content %}
        {% endblock %}
    </div>
</body>

</html>

index.html

{% extends 'base.html' %}

{% block title %}
    Index
{% endblock %}

{% block content %}
    <h1>Hello</h1>
{% endblock %}

home.html

{% extends 'base.html' %}

{% block title %}
    Home
{% endblock %}

{% block content %}
    {% if username %}
        <h1>Welcome {{ username }}</h1>
    {% elif users %}
        {% for username in users %}
            <h1>Welcome {{ username }}</h1>
        {% endfor %}
    {% else %}
        <a href={{ url_for('index') }}><button>Index</button></a>
    {% endif %}
{% endblock %}

改好之後,输入上面的三个 URL 的话,应该会得到一样的结果(废话,因为只是把它们拆开而已)。

看到这里,也大概知道它是如何运作的了吧!就是同样的东西共享,在需要填入不同东西的地方挖个洞、取个名字(名子随便取,但是尽量取有意义的名字),然後在子页面继承之後,输入名字与要填入的东西,就可以达成这样的效果。

那麽就大概这样,这边只有 HTML 相关的东西,有关 CSS 与 JavaScript 的东西,以及想要改位置的方式下一篇会讲到。

大家掰~掰~


<<:  Day16 开发套件 - 实作EventChannel

>>:  TailwindCSS 从零开始 - 简单认识 PostCSS

WordPress 显示最後更新日期的 3 种方法 (外挂、程序码、Post Meta Data) – 提高 SEO 排名

此篇文章将会教你如何在 WordPress 的文章上增加最後更新日期,让读者感觉到内容是最新有用的资...

硬体的讯号怎麽丢给软件?

预设 先要有一个开发板,可以接各种sensor。 可以先跟电脑有实体连接,这样就有指定的port可以...

认识 React Hooks 之三

今天是探索 Hooks 基础观念的最後一天,要学习的是 useImperativeHandle、us...

Day2 javascript用法

JavaScript 是可插入 HTML 页面的编程代码,插入 HTML 页面后,可由所有的现代浏览...

【LeetCode】Dynamic Programming II

先把之前的笔记随意复制贴上... 明天一定会改的 吧 最简单的 DP:fibonacci 数列 只要...