更通用的模板代码
多个页面怎么共用导航条、菜单、底部栏等通用的页面组件
之前我们用到了导航条,而如何直接共用此导航条而不额外复制代码,就是本篇要介绍的内容
1. 模板继承
http://docs.jinkan.org/docs/jinja2/templates.html#template-inheritance
Jinja 中最强大的部分就是模板继承。模板继承允许你构建一个包含你站点共同元素的基 本模板“骨架”,并定义子模板可以覆盖的
块
。
具体到咱们的代码:
1.1 基本模板
核心:所有的 {% block %}
标签告诉模板引擎子模板可以覆盖模板中的这些部分。
新建 apps/templates/base.html
文件:
<!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 子模板
一个子模板看起来是这样:
{% 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
文件:
{% 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
标签渲染(包含)另一个模板并将结果输出到当前模板中。
示例代码:
{% include 'header.html' %}
Body goes here.
{% include 'footer.html' %}
我们的导航条代码就很适合
新建 apps/templates/nav.html
文件:
<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
文件代码如下:
{% 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 %}
标签,重构了我们的首页
看看代码文件层级结构:
.
├── apps
│ └── templates
│ ├── base.html
│ ├── index.html
│ └── nav.html
└── server.py
2 directories, 4 files
至此,我们的页面样式算是定下来了,其它页面与首页 apps/templates/index.html
用法类似;可以愉快的写其它不同页面了