[Golang] 網頁設計敎學:製作靜態網頁

    前言

    我們先前的範例皆回傳純文字頁面,但實務上我們會回傳 HTML 頁面給使用者觀看,或是回傳 XML (或 JSON) 文件來傳輸資料。本文說明在網頁程式中加入 HTML 頁面的方式。

    (反模式) 直接嵌入網頁

    HTML 文件在本質上是加了標籤 (tag) 的文字文件,所以我們可以直接把整個 HTML 文件當成是一個多行字串輸出。按照這個想法寫出以下 (不良的) 程式碼:

    package main
    
    import (
        "github.com/julienschmidt/httprouter"
        "net/http"
    )
    
    func main() {
        mux := httprouter.New()
        mux.GET("/", index)
    
        server := http.Server{
            Addr: "127.0.0.1:8080",
            Handler: mux,
        }
    
        server.ListenAndServe()
    }
    
    func index(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
        // NEVER DO THIS IN PRODUCTION CODE
        str := `<!DOCTYPE html>
    <html>
    <head><title>Hello, HTML</title></head>
    <body><h1>Hello, HTML</h1><p>Add more text here</p></body>
    </html>
    `
        w.Write([]byte(str))
    }
    

    實務上,我們當然不會這樣做。早期的 CGI 基本上就是用這個思維在寫程式,這套模式已經算是時代的眼淚,我們不需要重覆這樣的舊路線。

    使用模板 (Template)

    在實務上,我們會利用模板 (template) 將內容和版面進行初步的分離。模板是網頁的骨架,會預先寫好一些和板面相關的代碼,要使用模板時再填入原本尚未完成的內容即可。透過模板引擎 (template engine) 的處理,模板和填入的資料會合併後轉為頁面。理論上所有文字格式的內容都能透過這種模式輸出。

    在 Golang 網頁程式中,我們通常拿模板來輸出 HTML 頁面。XML 和 JSON 文件則會用相關函式庫來産生,不會直接用模板去生 XML 或 JSON 文件。

    以本例來說,我們在 views/index.html 加入以下模板:

    <!DOCTYPE html>
    <html>
    <head>
        <title>{{ . }}</title>
    </head>
    <body>
        <p>{{ . }}</p>
    </body>
    </html>
    

    在此模板中,{{ . }} 部分即是挖空的內容,我們可以依需求填入不同的內容。

    接著來看主程式的部分:

    package main
    
    import (
        "github.com/julienschmidt/httprouter"
        "html/template"
        "net/http"
    )
    
    func main() {
        mux := httprouter.New()
        mux.GET("/", index)
    
        server := http.Server{
            Addr: "127.0.0.1:8080",
            Handler: mux,
        }
    
        server.ListenAndServe()
    }
    
    func index(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
        t := template.Must(template.ParseFiles("views/index.html"))
    
        t.Execute(w, "Hello, Template")
    }
    

    本程式的關鍵在於建立和使用模板,我們稍微說明一下。如果想查 API 的使用方式,請查閱 http/template 的文件。

    使用 template.Must 可以建立模板,其函式原型如下:

    func template.Must(tmpl, error) *tmpl
    

    但我們的範例是這樣:

    template.Must(template.ParseFiles("views/index.html"))
    

    如果看範例,會以為我們只傳入一個參數。但實際上我們傳入兩個參數,因為 template.ParseFiles 即會回傳兩個參數,所以可以滿足 template.Must 的 API。會有這樣的現象是因為 template.Must 是設計來搭配其他函式,以簡化建立模板的過程。

    接著來看以 Execute 函式生成模板的函式原型:

    func tmpl.Execute(out, data) err
    

    out 是輸出的目標,在本範例是 http.ResponseWriterdata 利用空介面的特性,可視需求傳入不同的東西。理論上要檢查是否引發錯誤,但本範例為了簡化程式碼,省略這個步驟。

    結語

    在本文中,我們以簡短的範例來展示如何在 Golang 網頁程式中使用模板。在後續的文章中,我們會介紹 Golang 的模板的語法。

    【分享本文】
    Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email
    【追蹤本站】
    Facebook Facebook Twitter Plurk