
2.3 使用Flask-Bootstrap扩展
Bootstrap是推特(Twitter)公司开发的一个开源框架,官方地址是http://getbootstrap.com/。使用Bootstrap可以快速开发出整洁的用户界面网页,这些网页还能兼容当前市面中所有的浏览器。在本节的内容中,将详细讲解在Flask Web程序中通过Flask-Bootstrap扩展使用Bootstrap的知识。

2.3.1 Flask-Bootstrap扩展基础
Bootstrap是一个典型的客户端框架,要想在Python程序中集成Bootstrap,需要对模板进行一些必要的改动。不过,更简单的方法是使用一个名为Flask-Bootstrap的Flask扩展。使用如下所示的pip命令安装Flask-Bootstrap。

在现实中,通常在创建程序实例时初始化Flask扩展,例如下面是初始化Flask-Bootstrap的演示代码。

其中Flask-Bootstrap是从flask.ext命名空间中导入的,然后把程序实例传入构造方法进行初始化。在导入Flask-Bootstrap框架并初始化之后,就可以在程序中使用一个包含所有Boot-strap文件的基模板。为了让程序扩展为一个具有基本页面结构的基模板,这个基模板需要使用Jinja2的模板继承机制来引入Bootstrap中的元素。
在内置的Flask-Bootstrap模板文件base.html中定义了很多块,开发者可以在衍生模板中使用这些块。下面列出了所有可用的块。
• doc:表示整个HTML文档。
• html_attribs:对应<html>标签的属性。
• html:对应<html>标签中的内容。
• head:对应<head>标签中的内容。
• title:对应<title>标签中的内容。
• metas:对应一组<meta>标签的内容。
• styles:对应定义CSS样式表标签的内容。
• body_attribs:对应<body>标签的属性。
• body:对应<body> 标签中的内容。
• navbar:对应导航条标签<navbar>的内容。
• content:对应用户定义的页面内容。
• scripts:对应声明JavaScript标签的内容。
上面的块都是Flask-Bootstrap内置定义的,就跟编程语言的标识符一样,我们不能自定义和上面同名的标签。通常在styles和scripts块中声明Bootstrap所需要的文件,如果需要在程序中向已经有内容的块中添加新的内容,必须使用Jinja2中的super()函数实现调用。假如想在子模板文件中添加新的JavaScript文件,需要通过下面的演示代码定义scripts块。

2.3.2 在Flask Web中使用Flask-Bootstrap扩展
在下面的实例中,演示了在Flask Web中使用Flask-Bootstrap扩展的过程。
源码路径:daima\2\2-3\untitled\
1)首先看Python文件untitled.py,通过代码“bootstrap=Bootstrap(app)”为Flask扩展Bootstrap实现实例初始化,这行代码是Flask-Bootstrap的初始化方法。具体实现代码如下所示。

2)编写模板文件base.html,为了实现模板继承,使用Jinja2指令extends从Flask-Bootstrap中导入bootstrap/base.html。在模板文件base.html中定义了可在子模板中重定义的块,可以将指令block和endblock定义的块中的内容添加到基模板中。文件base.html的具体实现代码如下所示。


在上述模板文件base.html中定义了基模板提供的3个块,可以在子模板中重新定义这3个块。这3个块的具体说明如下所示。
• title:其中的内容在渲染后的HTML文档的<title> 标签中显示。
• navbar:表示页面中的导航条,在本实例中使用Bootstrap组件定义了一个简单的导航条。
• content:表示页面中的主体内容,在content块中有一个<div>容器,在本实例中包含了欢迎信息。
3)在模板文件index.html中继承模板文件base.html的内容,具体实现代码如下所示。

在浏览器中输入“http://127.0.0.1:5000/”后会显示指定的模板样式,实现一个导航效果。执行效果如图2-6所示。

图2-6 执行效果
2.3.3 自定义错误页面
在现实应用中,常见的找不到URL的错误代码有两个。
• 404:客户端请求未知页面或路由时显示。
• 500:因无法解析发生的错误。
读者应该有这个体验:如果在浏览器中输入了一个不可用的URL地址,那么会显示一个状态码为404的错误页面。但是这个错误页面的外观不够美观,严重影响了用户体验。正因如此,所以市面中专业网站的做法是设计一个美观的页面来作为URL出错时显示的页面。在Flask Web程序中,可以使用基于模板的自定义错误页面。
为了更加友好地处理404和500这两种错误类型,提高用户体验,可以编写两个函数来设置当发生上述错误时所展示的页面。例如在下面的演示代码中,演示了为上述两种错误代码设置自定义处理程序的方法。

然后接下来在模板目录“templates”下创建模板文件404.html和500.html,然后使用这两个文件分别设置要显示的提示信息。但是这样做比较烦琐,需要开发者编写一些代码才能实现。令Flask Web开发者幸运的是,Jinja2的模板继承机制可以很好地解决这一问题。我们可以在程序中定义一个基模板,其中包含处理两种错误的导航条,然后在子模板中定义页面内容。例如在下面的演示文件templates/base.html中,定义了一个继承自bootstrap/base.html的新模板,在里面定义了导航条。并且这个模板本身也可作为其他模板的基模板,例如templates/user.html、templates/404.html和templates/500.html。

在上述模板文件的content块中,在<div>容器中包含了一个名为page_content的新空块,块中的内容由衍生模板定义。此时在程序中使用的模板继承自这个模板,而不是直接继承自Flask-Bootstrap的基模板。我们可以编写一个展示404错误提示信息的页面,通过继承模板文件templates/base.html自定义实现,例如下面的演示代码。
