實作 - 從零開始用 Golang 寫網頁 - 08 在模板中使用佈局 layout

[實作] 從零開始用 Golang 寫網頁 : 08 在模板中使用佈局 layout

layout 是指將版面區分為多個區塊並方便進行規劃及整頓,而將模板中共同的區塊拉出來後,之後也方便做修改與維護,另外這裡也對先前的模板做點補充

模板補充

1
2
3
4
5
6
7
8
9
10
11
12
import (
"fmt"
"html/template"
"net/http"
"os"

"github.com/julienschmidt/httprouter"
log "github.com/sirupsen/logrus"
"github.com/urfave/negroni"

negronilogrus "github.com/meatballhat/negroni-logrus"
)
  • 原本 import 的模板套件為 "text/template",但實際要上線使用時,就要使用 "html/template" 套件,因為此套件會對 code injection 的情形進行防護,而 "text/template" 則沒有此功能
1
2
3
4
5
6
7
8
9
10
func index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
data := map[string]string{
"name": "Guest",
"someStr": "這是首頁",
}

t := template.Must(template.ParseFiles("./templates/index.html"))

t.Execute(w, data)
}

index

1
2
3
4
5
t, err := template.ParseFiles("./templates/index.html")

if err != nil {
fmt.Println("首頁開啟錯誤 : ", err)
}
  • 這邊原本是使用以上方法來處理錯誤事件,而其實 template.Must 的函式也能夠處理錯誤事件,若有錯誤他會直接引發 panic 來導致程序崩潰,這裡就表示模板解析有錯誤的話就會直接讓程序掛掉

    • 以下為 template.Must 的原始碼
1
2
3
4
5
6
func Must(t *Template, err error) *Template {
if err != nil {
panic(err)
}
return t
}

在模板中使用佈局 layout

1
2
3
4
5
6
7
8
9
10
11
12
13
func index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
data := map[string]string{
"name": "Guest",
"content": "這是首頁",
}

t := template.Must(template.ParseFiles("./views/layout.html", "./views/head.html", "./views/index.html"))

err := t.ExecuteTemplate(w, "layout", data)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
1
2
3
4
5
6
7
8
9
10
11
12
{{ define "layout" }}

<html>
<head>
{{ template "head" . }}
</head>
<body>
{{ template "content" . }}
</body>
</html>

{{ end }}
  • layout.html
1
2
3
4
5
{{ block "head" . }}

<title>Hello {{ .name }}</title>

{{ end }}
  • head.html
1
2
3
4
5
6
{{ block "content" . }}

<p>Hello {{ .name }}</p>
<div>{{ .content }}</div>

{{ end }}
  • index.html

index

  • 先前都是一次引入一個 html 檔案,這次一次引入三個,分別是 :

    • layout.html
    • head.html
    • index.html
  • 因為是使用 layout 所以使用了不同的函式 ExecuteTemplate() 來執行

layout.html

  • 這裡我們定義了 layout 區塊,在裡面我們將頁面拆分成 headcontent 兩個子區塊

    • 使用 template 語法將兩個區塊引入

head.html

  • head 區塊,主要將變數 name 帶入

index.html

  • content 區塊,不只將變數 name 帶入,另外也帶入了變數 content

結果

  • 上方的標頭為 head 區塊,而下方頁面處為 content 區塊

tags: 實作 Golang 網站
Author: Kenny Li
Link: https://kennyliblog.nctu.me/2020/09/14/Golang-Web8/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.