我自己是 PHP 後端工程師,常常在寫網頁、常碰 Javascript , html , css 等等,所以,在學這個 Go 的過程當中,也來學習用 go 寫一個網頁吧!
Go 與網頁常常有用到的一個套件就叫做 net/http , 他同時也可以做網頁的爬蟲,等等讓我娓娓道來~
網頁版 HelloWorld !
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 的第二個參數可以將資料塞入樣板中。而樣板中很重要的是可以使用{{.}}
等符號
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 就像以下這樣寫
<!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 首先是主程式:
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
<!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>
小君曰:我要學習的還很多咧