翻译至http://jan.newmarch.name/go/template/chapter-template.html
第九章
很多编程语言都有字符串之间转换的机制,而GO语言则是通过模板来将一个对象的内容来作为参数传递从而字符串的转换。此方式不仅可以在重写HTML时插入对象值,也适用于其他方面。注意,本章内容并没有明确给出网络的工作方式,但对于网络编程方式很有用处。
Introduction 介绍大多数服务器端语言的机制主要是在静态页面插入一个动态生成的组件,如清单列表项目。典型的例子是在JSP、PHP和许多其他语言的脚本中。GO的template
包中采取了相对简单的脚本化语言。
因为新的template包是刚刚被采用的,所有现在的template包中的文档少的可怜,旧的old/template
包中也还存有少量的旧模板。新发布的帮助页面还没有关于新包的文档。关于template包的更改请参阅r60 (released 2011/09/07).
在这里,我们描述了这个新包。该包是描述了通过使用对象值改变了原来文本的方式从而在输入和输出时获取不同的文本。与JSP或类似的不同,它的作用不仅限于HTML文件,但在那可能会有更大的作用。
源文件被称作 template ,包括文本传输方式不变,以嵌入命令可以作用于和更改文本。命令规定如 {{ ... }}
,类似于JSP命令 和PHP命令
。
模板应用于GO对象中.GO对象的字段被插入到模板后,你就能从域中“挖”到他的子域,等等。当前对象以'.'代替, 所以把当前对象当做字符串插入时,你可以采用{{.}}
的方式。这个包默认采用 fmt
包来作为插入值的字符串输出。
要插入当前对象的一个字段的值,你使用的字段名前加前缀 '.'。 例如, 如果要插入的对象的类型为
type Person struct {
Name string
Age int
Emails []string
Jobs []*Jobs
}
那么你要插入的字段 Name
和 Age
如下
The name is {{.Name}}.
The age is {{.Age}}.
我们可以使用range
命令来循环一个数组或者链表中的元素。所以要获取 Emails
数组的信息,我们可以这么干
{{range .Emails}}
...
{{end}}
如果Job
定义为
type Job struct {
Employer string
Role string
}
如果我们想访问 Person
字段中的 Jobs
, 我们可以这么干 {{range .Jobs}}
。这是一种可以将当前对象转化为Jobs
字段的方式. 通过 {{with ...}} ... {{end}}
这种方式, 那么{{.}}
就可以拿到Jobs
字段了,如下:
{{with .Jobs}}
{{range .}}
An employer is {{.Employer}}
and the role is {{.Role}}
{{end}}
{{end}}
你可以用这种方法操作任何类型的字段,而不仅限于数组。亲,用模板吧!
当我们拥有了模板,我们将它应用在对象中生成一个字符串,用这个对象来填充这个模板的值。分两步来实现模块的转化和应用,并且输出一个Writer
, 如下
t := template.New("Person template")
t, err := t.Parse(templ)
if err == nil {
buff := bytes.NewBufferString("")
t.Execute(buff, person)
}
下面是一个例子来演示模块应用在对象上并且标准输入:
/**
* PrintPerson
*/
package main
import (
"fmt"
"html/template"
"os"
)
type Person struct {
Name string
Age int
Emails []string
Jobs []*Job
}
type Job struct {
Employer string
Role string
}
const templ = `The name is {{.Name}}.
The age is {{.Age}}.
{{range .Emails}}
An email is {{.}}
{{end}}
{{with .Jobs}}
{{range .}}
An employer is {{.Employer}}
and the role is {{.Role}}
{{end}}
{{end}}
`
func main() {
job1 := Job{Employer: "Monash", Role: "Honorary"}
job2 := Job{Employer: "Box Hill", Role: "Head of HE"}
person := Person{
Name: "jan",
Age: 50,
Emails: []string{"jan@newmarch.name", "jan.newmarch@gmail.com"},
Jobs: []*Job{&job1, &job2},
}
t := template.New("Person template")
t, err := t.Parse(templ)
checkError(err)
err = t.Execute(os.Stdout, person)
checkError(err)
}
func checkError(err error) {
if err != nil {
fmt.Println("Fatal error ", err.Error())
os.Exit(1)
}
}
输出如下:
The name is jan.
The age is 50.
An email is jan@newmarch.name
An email is jan.newmarch@gmail.com
An employer is Monash
and the role is Honorary
An employer is Box Hill
and the role is Head of HE
注意,上面有很多空白的输出,这是因为我们的模板中有很多空白。如果想消除它, 模板设置如下:
{{range .Emails}} An email is {{.}} {{end}}
在这个示例例中,我们用字符串应用于模板。你同样也可以用方法template.ParseFiles()
来从文件中下载模板。因为某些原因,我还不没搞清楚(在早期版本没有强制要求),关联模板的名字必须要与文件列表的第一个文件的基名相同。话说,这个是BUG吗?
上述转换到模板中插入的文本块。这些字符基本上是任意的,是任何字符串的字段值。如果我们希望它们出现的是HTML文档(或其他的特殊形式)的一部分,那么我们将不得不脱离特定的字符序列。例如,要显示任意文本在HTML文档中,我们要将“{. | html}} {.{range .
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?