06-更通用的模板代码

  • 阅读: 376
  • 更新: 2022-04-29

多个页面怎么共用导航条、菜单、底部栏等通用的页面组件
之前我们用到了导航条,而如何直接共用此导航条而不额外复制代码,就是本篇要介绍的内容

1. 模板继承

http://docs.jinkan.org/docs/jinja2/templates.html#template-inheritance

Jinja 中最强大的部分就是模板继承。模板继承允许你构建一个包含你站点共同元素的基 本模板“骨架”,并定义子模板可以覆盖的

具体到咱们的代码:

1.1 基本模板

核心:所有的 {% block %} 标签告诉模板引擎子模板可以覆盖模板中的这些部分。
新建 apps/templates/base.html 文件:

 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
<!doctype html>
<html lang="zh-CN">
  <head>
    <!-- 必须的 meta 标签 -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap 的 CSS 文件 -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css">

    <!-- Bootstrap 的 JS 文件 -->
    <script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.bundle.min.js"></script>

    <title>Hello, world!</title>

    {% block title %}{% endblock %}
    {% block extra_head %}{% endblock %}
  </head>
  <body>
    {% block nav %}{% endblock %}
    {% block content %}{% endblock %}
    {% block footer %}{% endblock %}
  </body>
</html>

上面总共定义了 5 个 {% block %} 标签。名称均是自定义的,个数随意,不够再加

1.2 子模板

一个子模板看起来是这样:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
{% extends "base.html" %}
{% block title %}Index{% endblock %}
{% block head %}
    {{ super() }}
    <style type="text/css">
        .important { color: #336699; }
    </style>
{% endblock %}
{% block content %}
    <h1>Index</h1>
    <p class="important">
      Welcome on my awesome homepage.
    </p>
{% endblock %}

我们按照上述代码修改一下 apps/templates/index.html 文件:

 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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
{% extends 'base.html' %}

{% block content %}
  <nav class="navbar navbar-expand-lg navbar-light bg-light">
    <a class="navbar-brand" href="#">Navbar</a>
    <button class="navbar-toggler" type="button" data-toggle="collapse"
        data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent"
        aria-expanded="false" aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
    </button>

    <div class="collapse navbar-collapse" id="navbarSupportedContent">
      <ul class="navbar-nav mr-auto">
        <li class="nav-item active">
          <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
        </li>
        <li class="nav-item">
          <a class="nav-link" href="#">Link</a>
        </li>
        <li class="nav-item dropdown">
          <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown"
              role="button" data-toggle="dropdown" aria-expanded="false">
            Dropdown
          </a>
          <div class="dropdown-menu" aria-labelledby="navbarDropdown">
            <a class="dropdown-item" href="#">Action</a>
            <a class="dropdown-item" href="#">Another action</a>
            <div class="dropdown-divider"></div>
            <a class="dropdown-item" href="#">Something else here</a>
          </div>
        </li>
        <li class="nav-item">
          <a class="nav-link disabled">Disabled</a>
        </li>
      </ul>
      <form class="form-inline my-2 my-lg-0">
        <input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search">
        <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
      </form>
    </div>
  </nav>

  <div class="container">
    <h1>Hello, world!</h1>

    <button type="button" class="btn btn-primary">Primary</button>
    <button type="button" class="btn btn-secondary">Secondary</button>
    <button type="button" class="btn btn-success">Success</button>
    <button type="button" class="btn btn-danger">Danger</button>
    <button type="button" class="btn btn-warning">Warning</button>
    <button type="button" class="btn btn-info">Info</button>
    <button type="button" class="btn btn-light">Light</button>
    <button type="button" class="btn btn-dark">Dark</button>
    <button type="button" class="btn btn-link">Link</button>
  </div>
{% endblock %}

访问页面发现页面还和之前一样
{% extend %} 标签是这里的关键。它告诉模板引擎这个模板“继承”另一个模板。
我们就是继承了上面的基本模板 {% extends 'base.html' %}

2. 模板包含

http://docs.jinkan.org/docs/jinja2/templates.html#id25

include 标签渲染(包含)另一个模板并将结果输出到当前模板中。
示例代码:

1
2
3
{% include 'header.html' %}
Body goes here.
{% include 'footer.html' %}

我们的导航条代码就很适合
新建 apps/templates/nav.html 文件:

 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
31
32
33
34
35
36
37
38
<nav class="navbar navbar-expand-lg navbar-light bg-light">
  <a class="navbar-brand" href="#">Navbar</a>
  <button class="navbar-toggler" type="button" data-toggle="collapse"
      data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent"
      aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>

  <div class="collapse navbar-collapse" id="navbarSupportedContent">
    <ul class="navbar-nav mr-auto">
      <li class="nav-item active">
        <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#">Link</a>
      </li>
      <li class="nav-item dropdown">
        <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown"
            role="button" data-toggle="dropdown" aria-expanded="false">
          Dropdown
        </a>
        <div class="dropdown-menu" aria-labelledby="navbarDropdown">
          <a class="dropdown-item" href="#">Action</a>
          <a class="dropdown-item" href="#">Another action</a>
          <div class="dropdown-divider"></div>
          <a class="dropdown-item" href="#">Something else here</a>
        </div>
      </li>
      <li class="nav-item">
        <a class="nav-link disabled">Disabled</a>
      </li>
    </ul>
    <form class="form-inline my-2 my-lg-0">
      <input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search">
      <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
    </form>
  </div>
</nav>

上面代码和 apps/templates/index.html 文件中的导航条代码一模一样
修改 apps/templates/index.html 文件,删除导航条代码,然后通过 {% include 'nav.html' %} 来引入导航条代码
最终 apps/templates/index.html 文件代码如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
{% extends 'base.html' %}

{% block nav %}
  {% include 'nav.html' %}
{% endblock %}

{% block content %}
  <div class="container">
    <h1>Hello, world!</h1>

    <button type="button" class="btn btn-primary">Primary</button>
    <button type="button" class="btn btn-secondary">Secondary</button>
    <button type="button" class="btn btn-success">Success</button>
    <button type="button" class="btn btn-danger">Danger</button>
    <button type="button" class="btn btn-warning">Warning</button>
    <button type="button" class="btn btn-info">Info</button>
    <button type="button" class="btn btn-light">Light</button>
    <button type="button" class="btn btn-dark">Dark</button>
    <button type="button" class="btn btn-link">Link</button>
  </div>
{% endblock %}

引入导航条代码放到了基本模板的 {% block nav %}{% endblock %}
此时访问页面,会发现页面依旧没有变化;但是我们的代码却发生了很大的变化,已经更加通用,精简了

3. 总结

我们通过 jinja2 模板中的 {% extend %}{% include %} 标签,重构了我们的首页
看看代码文件层级结构:

1
2
3
4
5
6
7
8
9
.
├── apps
│   └── templates
│       ├── base.html
│       ├── index.html
│       └── nav.html
└── server.py

2 directories, 4 files

至此,我们的页面样式算是定下来了,其它页面与首页 apps/templates/index.html 用法类似;可以愉快的写其它不同页面了


=== 全文完 ===


欢迎加入QQ群:855013471

京公网安备 11011302003970号 京ICP备2022012301号-1