這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
近期在使用Golang的net/http和html/template開發一個簡單的HAProxy負載平衡任務管理系統(見搭建高可用負載平衡組件及緩衝DNS一文說明)。
htmp/template在渲染頁面模板的時候預設會逸出字元串中的html標籤,但有時我們並不想轉義html標籤,以所示為例:
圖1中“ip:port列表(一行一個)”和“說明”兩個輸入框的內容行與行是以\n
分隔的;圖2中,這兩部分內容分別在表格的“後端機器列表”和“說明”兩列中展示,但行與行其實是以
分隔的;那麼在將資料存入資料庫之前或從資料庫中取出資料後,會將字串中的\n
替換為
。如果將替換後的資料以字串類型傳入模板,
標籤渲染後的效果就是
文本而不是換行。
有兩種方式避免html/template
轉義html標籤:
1.把字串類型資料轉換成template.HTML
類型再傳入模板進行渲染:
lti := listenTaskInfo{ Seq: seq, Id: row.Id, Servers: template.HTML(strings.Join(strings.Split(row.Servers, "-"), "
")), Vip: appConf.Vip, Vport: row.VPort, Comment: template.HTML(strings.Join(strings.Split(row.Comment, "\n"), "
")), LogOrNot: row.LogOrNot, DateTime: row.DateTime,}
2.html/template
允許根據需要為模板變數添加一個處理函數,在模板解析的時候該函數就能對模板變數做進一步的處理,如:
{{. | html}}
html/template
貌似並沒有內建這樣的函數讓其不轉義html標籤,但提供了介面讓我們按需自訂這類函數。那麼我們可以自訂一個函數-在模板解析的時候將模板變數轉換成template.HTML
類型,如(該例子來自How To Unescape Text In A Golang Html Template):
func unescaped (x string) interface{} { return template.HTML(x) }func renderTemplate(w http.ResponseWriter, tmpl string, view *Page) { t := template.New("") t = t.Funcs(template.FuncMap{"unescaped": unescaped}) t, err := t.ParseFiles("view.html", "edit.html") err = t.ExecuteTemplate(w, tmpl + ".html", view) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) }}
這段代碼使得模板解析的時候可以使用unescaped函數將模板變數x轉換成template.HTML
類型,關鍵是如下兩句:
// 定義函數unescapedfunc unescaped (x string) interface{} { return template.HTML(x) }// 在模板對象t中註冊unescapedt = t.Funcs(template.FuncMap{"unescaped": unescaped})
這樣,在模板中就可以使用unescaped函數了,如:
{{printf "%s" .Body | unescaped}} //[]byte{{.Body | unescaped}} //string
實現不轉義HTML標籤,本質上,這兩種方法是一樣的,只不過一種是在字串傳入模板之前將其轉換成template.HTML
類型,另一種是在字串傳入模板之後解析之時轉換。
除了template.HTML
類型,text/template
還定義了template.JS
、template.CSS
等資料類型。
參考
- html/template
- How To Unescape Text In A Golang Html Template