iT邦幫忙

2021 iThome 鐵人賽

DAY 8
0
Modern Web

Flask系列 第 8

Day 8 jinja (3)

前言

今天一樣是 jinja 的內容,會講到模板的繼承。這個在網頁有固定排版或是格式的時候很好用,不用一直重複複製貼上。就算網頁沒有固定排版,基本上 head、要引入的 CSS、JS 也可能有重複。簡單來說,我覺得這是一個一定會用到的功能,後面開始寫專案的時候也會用到。

範例

先來看個範例。base.htmlindex.html 都必須放在 templates/ 裡面。

app.py


from flask import Flask, render_template
app = Flask(__name__)

@app.route("/")
def index_page():
    user = "Cat"
    return render_template("index.html", user=user)


app.run(host="127.0.0.1", port=8080, debug=True)

base.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{% block title %}{% endblock %}</title>
</head>

<body>
    <nav>
        nav
    </nav>
    <main>
        {% block content %}
        {% endblock %}
    </main>
    <footer>
        footer
    </footer>
</body>

index.html

{% extends "base.html" %}

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

{% block content %}
<p>
    {{ user }}
</p>
{% endblock %}

app.py 和之前差不多,就把 user 傳入 jinja 處理。

base.html 裡面出現了 {% block %},他代表這是一個可以自由發揮的區塊,也就是非排版的部分,而 block 後面接的 titlecontent 則是這個 block 的名稱。我們在 base.html 定義好一些區塊,然後交給其他模板去寫,以此處為例就是下面的 index.html

最後我們看到 index.html,他在最一開始就宣告說這個模板是從 base.html 繼承來的,所以他會照著剛剛 base.html 的格式生成已經寫好的內容。接下來,我們把剛剛在 base.html 留下來的 block 一一填好。首先是 title,就跟剛剛的寫法一樣,需要 {% block title %}{% endblock %},但這次中間需要放入自己想要的網站標題,此處就用 Index Page 為例。下一個是 content,在這邊我們就把 flask 傳過來的 user 塞進去。這樣就完成了樣板的繼承,這時候打開瀏覽器應該可以看到它顯示出 nav、剛剛傳入的 userfooter

實作

最後我們來實作未來要用到的 base.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{% block title %}{% endblock %}</title>
    {% block extra_import %}
    {% endblock %}
</head>

<body>
    <nav>
        <!-- unauthorized -->
        <span><a href="/login">Login</a></span>
        <span><a href="/register">Register</a></span>
        <!-- normal user -->
        <span><a href="/dashboard">Dashboard</a></span>
        <span><a href="/posts">All posts</a></span>
        <span><a href="/post/add">Add post</a></span>
        <span><a href="/setting">Setting</a></span>
        <!-- admin -->
        <span><a href="/admin_dashboard/posts">Admin Dashboard for posts</a></span>
        <span><a href="/admin_dashboard/comments">Admin Dashboard for comments</a></span>
        <span><a href="/manage_user">Manage User</a></span>
    </nav>
    <main>
        {{ display_msg(get_flashed_messages(with_categories=True)) }}
        {% block content %}
        {% endblock %}
    </main>
    <footer>
        &copy; siriuskoan
    </footer>
</body>

</html>

這裡多數都是跟剛剛差不多的內容,比較特別的是我多放了一個 extra_import,在這裡可以放一些 CSS、JS 等等的,而他們要放在哪裡則是明天的主題。

nav 的部分我放了很多連結,同時也幫他們上了註解,很明顯我們不可能對所有人都顯示出一樣的 nav,所以在未來我們會在這裡做一些判斷來決定到底要怎麼顯示 nav

有了這個模板之後,我們未來所有的 HTML 都會繼承自他,可以大幅減少重複的內容。


上一篇
Day 7 jinja (2)
下一篇
Day 9 專案目錄結構
系列文
Flask30

尚未有邦友留言

立即登入留言