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 都会继承自他,可以大幅减少重复的内容。


<<:  拟定 ISMS 程序书撰写方向

>>:  D7: [漫画]工程师太师了-第4话

Day 4 Ruby 变数与资料型别 Variable and Data Type

写在前面 因为发现昨天在讲基础运算子的时候很多地方需要先知道变数跟资料型别,所以今天赶快来补充一下。...

受信任计算机系统评估标准(TCSEC)

TCSEC定义了评估可信计算系统的标准,该系统包括四个分类。每个分类可以分为几类。B分类的类别(B1...

Day 04 : 找不出的零钱 Non-constructible Change

先来看一下题目 Given an array of positive integers (repre...

Android Studio初学笔记-Day3--RelativeLayout

承上一篇,今天要分享的是另一个比较常见也比较广泛使用的布局。 RelativeLayout(相对布局...

AE-Lightning 雷电云特效2-Day24

竟然已经到了24天,终於快结束了~ 接续昨天的练习, 1.将Light图层Pre-compose起来...