11-Facelift
在本章中,我暂停一下后端的工作,并花点时间向你展示如何使应用看起来更加优雅和专业。
本章主要是用到了 前端的 Bootstrap
本章的GitHub链接为: Source, Diff, Zip

CSS 框架

虽然我们可以争辩说写代码不容易,但是与那些必须让网页在所有Web浏览器上具有良好一致外观的网页设计师相比,我们的痛苦不值一提。 虽然近年来这种情况得到一定程度的缓解,但是在一些浏览器中仍然存在着晦涩的错误或奇怪的设定,这使得设计网页的任务变得非常困难。 如果还需要兼容屏幕限制设备(诸如平板电脑和智能手机)的浏览器,则更加困难。
如果你和我一样,只是一个想创建出规范网页的开发人员,没有时间或兴趣去学习底层机制并通过编写原生HTML和CSS来实现它,那么唯一可行的解决方案是使用CSS框架来简化任务。 通过这种方式,你会失去一些创造性的自由,但另一方面,无需通过太多的功夫就可以让网页在所有浏览器中看起来都不错。 CSS框架为普通类型的用户界面元素提供了高级CSS类的集合,其中包含预定义样式。 大多数这样的框架还提供JavaScript插件,以实现不能纯粹使用HTML和CSS来完成的功能。

Bootstrap简介

最受欢迎的CSS框架之一是由Twitter推出的Bootstrap。 如果你想看看这个框架可以设计的页面类型,文档有一些示例
这些是使用Bootstrap来设置网页风格的一些好处:
    在所有主流网页浏览器中都有相似的外观
    自动处理PC桌面,平板电脑和手机屏幕尺寸
    可定制的布局
    精心设计的导航栏,表单,按钮,警示,弹出窗口等

Bootstrap美化

由于我们所有的页面都是继承自 templates/_base.html,所以我们需要在 _base.html 中引入 bootstrap
templates/_base.html
1
<html>
2
<head>
3
{{if .Title}}
4
<title>{{.Title}} - blog</title>
5
{{else}}
6
<title>Welcome to blog!</title>
7
{{end}}
8
9
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
10
11
<style>
12
.container {
13
max-width: 960px;
14
}
15
</style>
16
17
</head>
18
<body>
19
<div class="d-flex flex-column flex-md-row align-items-center p-3 px-md-4 mb-3 bg-white border-bottom shadow-sm">
20
<h5 class="my-0 mr-md-auto font-weight-normal">Blog</h5>
21
<nav class="my-2 my-md-0 mr-md-3">
22
<a class="p-2 text-dark" href="/">Home</a>
23
<a class="p-2 text-dark" href="/explore">Explore</a>
24
{{if .CurrentUser}}
25
<a class="p-2 text-dark" href="/user/{{.CurrentUser}}">Profile</a>
26
{{end}}
27
</nav>
28
29
{{if .CurrentUser}}
30
<a class="btn btn-outline-primary" href="/logout">Logout</a>
31
{{else}}
32
<a class="btn btn-outline-primary" href="/login">Login</a>
33
{{end}}
34
</div>
35
36
<div class="container">
37
{{template "content" .}}
38
</div>
39
40
<script src="https://code.jquery.com/jquery-3.3.1.min.js" crossorigin="anonymous"></script>
41
</body>
42
</html>
Copied!
接着我们主要优化的是表单和按钮
    所有表单上加上 class="form-control"
    所有按钮上加上 class="btn btn-outline-primary"
    所有的分页按钮优化
1
<nav aria-label="...">
2
<ul class="pagination justify-content-center">
3
{{ if gt .PrevPage 0 }}
4
<li class="page-item">
5
<a href="/user/{{.ProfileUser.Username}}?page={{.PrevPage}}">
6
<span class="page-link" aria-hidden="true">&larr; Newer Posts</span>
7
</a>
8
</li>
9
{{ else }}
10
<li class="page-item disabled">
11
<a href="#">
12
<span class="page-link" aria-hidden="true">&larr; Newer Posts</span>
13
</a>
14
</li>
15
{{ end }}
16
{{ if gt .NextPage 0 }}
17
<li class="page-item">
18
<a href="/user/{{.ProfileUser.Username}}?page={{.NextPage}}">
19
<span class="page-link" aria-hidden="true">Older Posts &rarr;</span>
20
</a>
21
</li>
22
{{ else }}
23
<li class="page-item disabled">
24
<a href="#">
25
<span class="page-link" aria-hidden="true">Older Posts &rarr;</span>
26
</a>
27
</li>
28
{{ end }}
29
30
</ul>
31
</nav>
Copied!
11-01
11-02
本小节 Diff

自定义 404 界面

我们现在的404界面还是 gorilla/mux 的默认界面,现在我们美化下
vm/notfound.go
1
package vm
2
3
// NotFoundMessage struct
4
type NotFoundMessage struct {
5
Flash string
6
}
Copied!
templates/404.html
1
<!doctype html>
2
<html lang="en">
3
<head>
4
<meta charset="utf-8">
5
<title>Page Not Found</title>
6
<meta name="viewport" content="width=device-width, initial-scale=1">
7
<style>
8
* {
9
line-height: 1.2;
10
margin: 0;
11
}
12
html {
13
color: #888;
14
display: table;
15
font-family: sans-serif;
16
height: 100%;
17
text-align: center;
18
width: 100%;
19
}
20
body {
21
display: table-cell;
22
vertical-align: middle;
23
margin: 2em auto;
24
}
25
h1 {
26
color: #555;
27
font-size: 2em;
28
font-weight: 400;
29
}
30
p {
31
margin: 0 auto;
32
width: 280px;
33
}
34
@media only screen and (max-width: 280px) {
35
body, p {
36
width: 95%;
37
}
38
h1 {
39
font-size: 1.5em;
40
margin: 0 0 0.3em;
41
}
42
}
43
</style>
44
</head>
45
<body>
46
{{if .Flash}}
47
<h1>{{.Flash}}</h1>
48
{{else}}
49
<h1>Page Not Found</h1>
50
{{end}}
51
<p>Sorry, but the page you were trying to view does not exist.</p>
52
</body>
53
</html>
Copied!
controller/home.go
1
...
2
r.NotFoundHandler = http.HandlerFunc(notfoundHandler)
3
r.HandleFunc("/404", notfoundHandler)
4
...
5
6
7
func notfoundHandler(w http.ResponseWriter, r *http.Request) {
8
flash := getFlash(w, r)
9
message := vm.NotFoundMessage{Flash: flash}
10
tpl, _ := template.ParseFiles("templates/404.html")
11
tpl.Execute(w, &message)
12
}
13
...
Copied!
运行程序,在浏览器中输入一个没有指定的 url,例如: http://127.0.0.1:8888/nosuchpage
11-03
本小节 Diff

Links