Go Template学习1

Go Templates

  • 接下来使用Go的基础模板,使用html/template包开发成熟的web应用.

  • text/template包
    使用模板创建动态内容是一个重要的方式,在运行时按照预定的格式生成动态的内容. 标准库html/template 包允许通过组合静态内容和动态内容创建动态的网页,动态内容会在运行时根据提供的数据结构进行解析转换.

html/template包提供了和text/template相同的接口,不同的是,html/template包通常是解析模板输出到HTML,text/template包则是文本的模板.以text/template开始,理解Go模板的语法,之后再使用html/template包. text/template 包可以创建数据驱动的模板得到输出的文本.

  • 使用text/template
    在运行的时候回根据给定的数据结构进行解析模板.模板的命令会反映到数据结构的元素.比如:结构体的字段可以映射到模板的命令,在模板中,这些命令会被双大括号包围 {{}}.

结构体字段应用到模板中的例子

// template
package main

import (
    "log"
    "os"
    "text/template"
)

type Note struct {
    Title       string
    Description string
}

const templ = `Note - Title:{{.Title}},Description:{{.Description}}`

func main() {
    note := Note{"text/template", "Template generates textual ouput"}

    //create a template with name
    t := template.New("note")

    //解析内容到模板
    t, err := t.Parse(templ)
    if err != nil {
        log.Fatal("Parse:", err)
        return
    }

    //将数据用到模板中
    if err := t.Execute(os.Stdout, note); err != nil {
        log.Fatal("Execute:", err)
        return
    }

}

//控制台输出
Note - Title:text/template,Description:Template generates textual ouput

在模板执行的时候,Note结构体的Title和Description字段会映射对象的值.模板快 {{.}}会在模板执行的时候进行上下文自动替换.此处的Note对象提供给了模板在模板执行的时候所以点(.)之后的字段会映射到Note对象对应的字段.

此处的模板是解析了一个字符串.如果是解析来自文件,使用 ParseFiles 方法

func (t *Template)ParseFiles(filenames ...string)(*Template ,error)

另外 ParseGlob方法会解析参数提供的表达式的对应模板.比如解析拓展名是 .tmpl的文件

t,err := template.ParseGlob("templates/*.tmpl")

Execute方法应用于一个解析过给定的数据对象的模板,同事写到一个输出设备.如果此时发生错误,执行会停止,但是可能有部分数据已经输出到设备.

总结起来解析一个文本模板的步骤如下:

1.定义一个映射到模板的数据对象
2.使用template.New方法创建一个*Template对象
3.调用Parse方法解析一个字符串到模板
4.执行模板的Execute方法,把给定的数据对象渲染到文本对象的字段.

下面的例子是把一个slice对象解析到模板中

// template
package main

import (
    "log"
    "os"
    "text/template"
)

type Note struct {
    Title       string
    Description string
}

const templ = `Notes are: {{range .}} Title:{{.Title}},Description:{{.Description}} {{end}}`

func main() {
    notes := []Note{
        {"text/template", "Template generates textual ouput"},
        {"html/template", "Template generates HTML ouput"},
    }

    //create a template with name
    t := template.New("note")

    //解析内容到模板
    t, err := t.Parse(templ)
    if err != nil {
        log.Fatal("Parse:", err)
        return
    }

    //将数据用到模板中
    if err := t.Execute(os.Stdout, notes); err != nil {
        log.Fatal("Execute:", err)
        return
    }

}

//控制台输出
Notes are:  Title:text/template,Description:Template generates textual ouput  Title:html/template,Description:Template generates HTML ouput

  • 定义明确命名的模板

模板定义可以使用 define和end来明确规定,define操作表示了模板的开始,end表示结束.

// define
package main

import (
    "log"
    "os"
    "text/template"
)

func main() {
    t, err := template.New("test").Parse(`{{define "T"}} Hello,{{.}}!{{end}}`)
    err = t.ExecuteTemplate(os.Stdout, "T", "World")
    if err != nil {
        log.Fatal("Execute:", err)
    }
}

//控制台输出
Hello World!

  • 模板中声明变量

可以在模板中声明变量,在声明之后的内容可以直接使用.声明变量的方式:在{{}}内 $variable.

{{ $note := "Sample String"}} //声明
{{$note}}           //调用变量

当使用range 函数获取到的变量,是每个枚举得出的元素.range得到key和value

{{range $key,$value := .}}

如果枚举的是字典,key就是字典的key值,value就是对应的value

使用html/template创建一个HTML页面

当我们创建web应用的时候,会用程序的数据去渲染UI界面.标准库的包html/template 可以很好的创建动态的web页面程序.我们创建web应用,会使用HTML,CSS和JavaScript创建好页面模板.

html/template 和text/template有相同的接口,但是输出到的是HTML页面.html/template不单单是生成HTML页面,还会防止代码的恶意注入.使用html/template包最多的优势在于安全的使用数据模型

这段代码展示了防止脚本注入:

// define
package main

import (
    "html/template"
    "log"
    "os"
)

func main() {
    t, err := template.New("test").Parse(`{{define "T"}} Hello,{{.}}!{{end}}`)
    err = t.ExecuteTemplate(os.Stdout, "T", "<script>alert('haha')</script>")
    if err != nil {
        log.Fatal("Execute:", err)
    }
}

//控制台输出
Hello,&lt;script&gt;alert(&#39;haha&#39;)&lt;/script&gt;!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,941评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,397评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,345评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,851评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,868评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,688评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,414评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,319评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,775评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,945评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,096评论 1 350
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,789评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,437评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,993评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,107评论 1 271
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,308评论 3 372
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,037评论 2 355

推荐阅读更多精彩内容