Template
這也太神奇惹吧XD,印象中 Hugo (?!) 有看過這樣的寫法
Remark
直接插入 data:{{.}}
struct 寫法,後面要加入欄位:{{.field}}
true 才會顯示中間的 data:{{if .}}xxx{{end}}
迴圈:{{range .}}{{.}}{{end}}
Example
Template
package main
import (
"log"
"os"
"text/template"
)
func main() {
// {{.}}
exeTemplate("i am not a {{.}} guy\n", "C#")
exeTemplate("i am a {{.}} guy\n", "Go")
// {{if .}}xxx{{end}}
exeTemplate("{{if .}}i like Go{{end}}\n", true)
exeTemplate("{{if .}}i like C#{{end}}\n", false)
// {{range .}}{{.}}{{end}}
exeTemplate("{{range .}}i am a {{.}} guy\n{{end}}\n", []string{"Go", "Java", "Python"})
// {{.field}} struct 寫法
exeTemplate("{{.Name}} language's salary is {{.Salary}}K.{{if .IsPopular}} Besides, it's very popular.{{end}}\n",
Language{Name: "Go", Salary: 121, IsPopular: true})
}
func exeTemplate(text string, data interface{}) {
tmpl, err := template.New("test").Parse(text)
check(err)
err = tmpl.Execute(os.Stdout, data) // Stdout (standard output) -> terminal
check(err)
}
func check(err error) {
if err != nil {
log.Fatal(err)
}
}
type Language struct {
Name string
Salary int
IsPopular bool
}
簽到簿應用程式
- main.go
package main
import (
"bufio"
"fmt"
"html/template"
"log"
"net/http"
"os"
)
func main() {
http.HandleFunc("/guestbook", viewHandler)
http.HandleFunc("/guestbook/new", newHandler)
http.HandleFunc("/guestbook/create", createHandler)
err := http.ListenAndServe(":8080", nil)
log.Fatal(err)
}
func viewHandler(writer http.ResponseWriter, request *http.Request) {
signatures := getSignatures("signatures.txt")
tmpl, err := template.ParseFiles("view.html")
check(err)
guestBook := GuestBook{SignatureCount: len(signatures), Signatures: signatures}
err = tmpl.Execute(writer, guestBook)
check(err)
}
func newHandler(writer http.ResponseWriter, request *http.Request) {
tmpl, err := template.ParseFiles("new.html")
check(err)
err = tmpl.Execute(writer, nil)
check(err)
}
func createHandler(writer http.ResponseWriter, request *http.Request) {
signature := request.FormValue("signature")
// OR 位元運算子
options := os.O_WRONLY | os.O_APPEND | os.O_CREATE
file, err := os.OpenFile("signatures.txt", options, os.FileMode(0600))
check(err)
_, err = fmt.Fprintln(file, signature)
check(err)
err = file.Close()
check(err)
http.Redirect(writer, request, "/guestbook", http.StatusFound)
}
type GuestBook struct {
SignatureCount int
Signatures []string
}
func getSignatures(fileName string) []string {
var result []string
file, err := os.Open(fileName)
if os.IsNotExist(err) {
return nil
}
check(err)
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
result = append(result, scanner.Text())
}
check(scanner.Err())
return result
}
func check(err error) {
if err != nil {
log.Fatal(err)
}
}
- view.html
<h1>Guestbook</h1>
<div>
{{.SignatureCount}} total signature -
<a href="/guestbook/new">Add Your Signature</a>
</div>
<div>
{{range .Signatures}}
<p>{{.}}</p>
{{end}}
</div>
- new.html
<h1>Add a Signature</h1>
<form action="/guestbook/create" method="post">
<div><input type="text" name="signature" id="" /></div>
<div><input type="submit" /></div>
</form>