10

Golang中如何让html/template不转义html标签

 3 years ago
source link: https://studygolang.com/articles/1741?fr=sidebar
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Golang中如何让html/template不转义html标签

youngsterxyf · 2014-11-05 09:48:11 · 13997 次点击 · 预计阅读时间 2 分钟 · 不到1分钟之前 开始浏览    
这是一个创建于 2014-11-05 09:48:11 的文章,其中的信息可能已经有所发展或是发生改变。

近期在使用Golang的net/httphtml/template开发一个简单的HAProxy负载均衡任务管理系统(见搭建高可用负载均衡组件及缓存DNS一文说明)。

htmp/template在渲染页面模板的时候默认会转义字符串中的html标签,但有时我们并不想转义html标签,以下图所示为例:

add_haproxy_balance_task

list_haproxy_balance_task

图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/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类型,关键是如下两句:

// 定义函数unescaped
func unescaped (x string) interface{} { return template.HTML(x) }
// 在模板对象t中注册unescaped
t = t.Funcs(template.FuncMap{"unescaped": unescaped})

这样,在模板中就可以使用unescaped函数了,如:

{{printf "%s" .Body | unescaped}} //[]byte
{{.Body | unescaped}} //string

实现不转义HTML标签,本质上,这两种方法是一样的,只不过一种是在字符串传入模板之前将其转换成template.HTML类型,另一种是在字符串传入模板之后解析之时转换。

除了template.HTML类型,text/template还定义了template.JStemplate.CSS等数据类型。


有疑问加站长微信联系(非本文作者)

280

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK