我自己是PHP 後端工程師,常常在寫網頁、常碰Javascript , html , css 等等,所以,在學這個Go的過程當中,也來學習用go寫一個網頁吧!
Go 與網頁常常有用到的一個套件就叫做 net/http , 他同時也可以做網頁的爬蟲,等等讓我娓娓道來~
網頁版HelloWorld !
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
package main
import (
"log"
"net/http"
)
func viewHandler(writer http.ResponseWriter, request *http.Request){
message := []byte("Hello World")
_,err := writer.Write(message)
if err != nil {
log.Fatal(err)
}
}
func main(){
http.HandleFunc("/hello",viewHandler)
err := http.ListenAndServe("localhost:8080",nil)
log.Fatal(err)
}
|
Template
如果網頁只是簡單的HelloWorld 怎麼行?在Go 裡面還有另外一個套件:html/template , 而使用Execute 的第二個參數可以將資料塞入樣板中。而樣板中很重要的是可以使用{{.}} 等符號
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
|
package main
import (
"log"
"net/http"
"html/template"
)
type TemplateData struct {
Name string
}
func viewHandler(writer http.ResponseWriter, request *http.Request){
html, err := template.ParseFiles("view.html")
if err != nil {
log.Fatal(err)
}
data := TemplateData{Name:"Jimmy"}
err = html.Execute(writer,data)
if err != nil {
log.Fatal(err)
}
}
func main(){
http.HandleFunc("/",viewHandler)
err := http.ListenAndServe("localhost:8080",nil)
log.Fatal(err)
}
|
上面我們有一段template.ParseFiles("view.html")
,而view.html 就像以下這樣寫
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<!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>Document</title>
</head>
<body>
<h1>Hello World</h1>
#Name: {{.Name}}
</body>
</html>
|
接下來,讓這裡筆記一下樣板中常見的樣式
- {{.Name}} : 塞入名稱為Name
- {{ if .Paid }} … {{ end }}: if paid 為 true , 才能執行if 的區塊
- {{ range .Charges }} … {{ . }}… {{ end}}: for 迴圈的區塊,根據Charges 裡面的項目依序列出資料
最後,寫個Todolist 吧!
完整程式碼請參考我的github : https://github.com/r567tw/golang-simple-todolist
首先是主程式:
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
57
58
59
60
61
62
63
64
|
package main
import (
"bufio"
"html/template"
"log"
"net/http"
"os"
"fmt"
)
type TodoList struct {
Todos []string
}
func getTodos(fileName string) []string {
var todos []string
file, err := os.Open(fileName)
if os.IsNotExist(err) {
return nil
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
todos = append(todos, scanner.Text())
}
return todos
}
func viewHandler(writer http.ResponseWriter, request *http.Request) {
html, err := template.ParseFiles("view.html")
todos := getTodos("todolist.txt")
if err != nil {
log.Fatal(err)
}
todolist := TodoList{
Todos: todos,
}
err = html.Execute(writer, todolist)
if err != nil {
log.Fatal(err)
}
}
func todoCreateHandler(writer http.ResponseWriter, request *http.Request) {
task := request.FormValue("task")
file, _ := os.OpenFile("todolist.txt", os.O_WRONLY | os.O_APPEND | os.O_CREATE , os.FileMode(0600))
fmt.Fprintln(file, task)
defer file.Close()
http.Redirect(writer, request, "/", http.StatusFound)
}
func main() {
http.HandleFunc("/", viewHandler)
http.HandleFunc("/todo/create", todoCreateHandler)
err := http.ListenAndServe("localhost:8080", nil)
log.Fatal(err)
}
|
我將Todo 存在檔案todolist.txt 當中
之後就是簡單地建立一下我的呈現畫面,因為我將創建的表單也放進同一頁,所以我就只要單一個檔案:view.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
<!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>Document</title>
</head>
<body>
<h1>Golang Simple Todo list</h1>
<form action="/todo/create" method="post">
<input type="text" name="task">
<button>Create Todo</button>
</form>
<ul>
{{range .Todos}}
<li>{{.}}</li>
{{end}}
</ul>
</body>
</html>
|
小君曰:我要學習的還很多咧