Add 0.7.4.md syntax highlighting

This commit is contained in:
vCaesar
2016-12-18 16:05:32 +08:00
parent fc8c273498
commit f2b2821f0c

View File

@@ -12,6 +12,7 @@ Web应用反馈给客户端的信息中的大部分内容是静态的不变
## Go模板使用 ## Go模板使用
在Go语言中我们使用`template`包来进行模板处理,使用类似`Parse``ParseFile``Execute`等方法从文件或者字符串加载模板然后执行类似上面图片展示的模板的merge操作。请看下面的例子 在Go语言中我们使用`template`包来进行模板处理,使用类似`Parse``ParseFile``Execute`等方法从文件或者字符串加载模板然后执行类似上面图片展示的模板的merge操作。请看下面的例子
```Go
func handler(w http.ResponseWriter, r *http.Request) { func handler(w http.ResponseWriter, r *http.Request) {
t := template.New("some template") //创建一个模板 t := template.New("some template") //创建一个模板
@@ -19,7 +20,7 @@ Web应用反馈给客户端的信息中的大部分内容是静态的不变
user := GetUser() //获取当前用户信息 user := GetUser() //获取当前用户信息
t.Execute(w, user) //执行模板的merger操作 t.Execute(w, user) //执行模板的merger操作
} }
```
通过上面的例子我们可以看到Go语言的模板操作非常的简单方便和其他语言的模板处理类似都是先获取数据然后渲染数据。 通过上面的例子我们可以看到Go语言的模板操作非常的简单方便和其他语言的模板处理类似都是先获取数据然后渲染数据。
为了演示和测试代码的方便,我们在接下来的例子中采用如下格式的代码 为了演示和测试代码的方便,我们在接下来的例子中采用如下格式的代码
@@ -33,6 +34,7 @@ Web应用反馈给客户端的信息中的大部分内容是静态的不变
### 字段操作 ### 字段操作
Go语言的模板通过`{{}}`来包含需要在渲染时被替换的字段,`{{.}}`表示当前的对象这和Java或者C++中的this类似如果要访问当前对象的字段通过`{{.FieldName}}`,但是需要注意一点:这个字段必须是导出的(字段首字母必须是大写的),否则在渲染的时候就会报错,请看下面的这个例子: Go语言的模板通过`{{}}`来包含需要在渲染时被替换的字段,`{{.}}`表示当前的对象这和Java或者C++中的this类似如果要访问当前对象的字段通过`{{.FieldName}}`,但是需要注意一点:这个字段必须是导出的(字段首字母必须是大写的),否则在渲染的时候就会报错,请看下面的这个例子:
```Go
package main package main
@@ -51,8 +53,9 @@ Go语言的模板通过`{{}}`来包含需要在渲染时被替换的字段,`{{
p := Person{UserName: "Astaxie"} p := Person{UserName: "Astaxie"}
t.Execute(os.Stdout, p) t.Execute(os.Stdout, p)
} }
```
上面的代码我们可以正确的输出`hello Astaxie`,但是如果我们稍微修改一下代码,在模板中含有了未导出的字段,那么就会报错 上面的代码我们可以正确的输出`hello Astaxie`,但是如果我们稍微修改一下代码,在模板中含有了未导出的字段,那么就会报错
```Go
type Person struct { type Person struct {
UserName string UserName string
@@ -60,7 +63,7 @@ Go语言的模板通过`{{}}`来包含需要在渲染时被替换的字段,`{{
} }
t, _ = t.Parse("hello {{.UserName}}! {{.email}}") t, _ = t.Parse("hello {{.UserName}}! {{.email}}")
```
上面的代码就会报错,因为我们调用了一个未导出的字段,但是如果我们调用了一个不存在的字段是不会报错的,而是输出为空。 上面的代码就会报错,因为我们调用了一个未导出的字段,但是如果我们调用了一个不存在的字段是不会报错的,而是输出为空。
如果模板中输出`{{.}}`这个一般应用于字符串对象默认会调用fmt包输出字符串的内容。 如果模板中输出`{{.}}`这个一般应用于字符串对象默认会调用fmt包输出字符串的内容。
@@ -72,6 +75,7 @@ Go语言的模板通过`{{}}`来包含需要在渲染时被替换的字段,`{{
- {{with}}操作是指当前对象的值,类似上下文的概念 - {{with}}操作是指当前对象的值,类似上下文的概念
详细的使用请看下面的例子: 详细的使用请看下面的例子:
```Go
package main package main
@@ -109,9 +113,10 @@ Go语言的模板通过`{{}}`来包含需要在渲染时被替换的字段,`{{
Friends: []*Friend{&f1, &f2}} Friends: []*Friend{&f1, &f2}}
t.Execute(os.Stdout, p) t.Execute(os.Stdout, p)
} }
```
### 条件处理 ### 条件处理
在Go模板里面如果需要进行条件判断那么我们可以使用和Go语言的`if-else`语法类似的方式来处理如果pipeline为空那么if就认为是false下面的例子展示了如何使用`if-else`语法: 在Go模板里面如果需要进行条件判断那么我们可以使用和Go语言的`if-else`语法类似的方式来处理如果pipeline为空那么if就认为是false下面的例子展示了如何使用`if-else`语法:
```Go
package main package main
@@ -133,44 +138,54 @@ Go语言的模板通过`{{}}`来包含需要在渲染时被替换的字段,`{{
tIfElse = template.Must(tIfElse.Parse("if-else demo: {{if `anything`}} if部分 {{else}} else部分.{{end}}\n")) tIfElse = template.Must(tIfElse.Parse("if-else demo: {{if `anything`}} if部分 {{else}} else部分.{{end}}\n"))
tIfElse.Execute(os.Stdout, nil) tIfElse.Execute(os.Stdout, nil)
} }
```
通过上面的演示代码我们知道`if-else`语法相当的简单,在使用过程中很容易集成到我们的模板代码中。 通过上面的演示代码我们知道`if-else`语法相当的简单,在使用过程中很容易集成到我们的模板代码中。
> 注意if里面无法使用条件判断例如.Mail=="astaxie@gmail.com"这样的判断是不正确的if里面只能是bool值 > 注意if里面无法使用条件判断例如.Mail=="astaxie@gmail.com"这样的判断是不正确的if里面只能是bool值
### pipelines ### pipelines
Unix用户已经很熟悉什么是`pipe`了,`ls | grep "beego"`类似这样的语法你是不是经常使用,过滤当前目录下面的文件,显示含有"beego"的数据表达的意思就是前面的输出可以当做后面的输入最后显示我们想要的数据而Go语言模板最强大的一点就是支持pipe数据在Go语言里面任何`{{}}`里面的都是pipelines数据例如我们上面输出的email里面如果还有一些可能引起XSS注入的那么我们如何来进行转化呢 Unix用户已经很熟悉什么是`pipe`了,`ls | grep "beego"`类似这样的语法你是不是经常使用,过滤当前目录下面的文件,显示含有"beego"的数据表达的意思就是前面的输出可以当做后面的输入最后显示我们想要的数据而Go语言模板最强大的一点就是支持pipe数据在Go语言里面任何`{{}}`里面的都是pipelines数据例如我们上面输出的email里面如果还有一些可能引起XSS注入的那么我们如何来进行转化呢
```Go
{{. | html}} {{. | html}}
```
在email输出的地方我们可以采用如上方式可以把输出全部转化html的实体上面的这种方式和我们平常写Unix的方式是不是一模一样操作起来相当的简便调用其他的函数也是类似的方式。 在email输出的地方我们可以采用如上方式可以把输出全部转化html的实体上面的这种方式和我们平常写Unix的方式是不是一模一样操作起来相当的简便调用其他的函数也是类似的方式。
### 模板变量 ### 模板变量
有时候,我们在模板使用过程中需要定义一些局部变量,我们可以在一些操作中申明局部变量,例如`with``range``if`过程中申明局部变量,这个变量的作用域是`{{end}}`之前Go语言通过申明的局部变量格式如下所示 有时候,我们在模板使用过程中需要定义一些局部变量,我们可以在一些操作中申明局部变量,例如`with``range``if`过程中申明局部变量,这个变量的作用域是`{{end}}`之前Go语言通过申明的局部变量格式如下所示
```Go
$variable := pipeline $variable := pipeline
```
详细的例子看下面的: 详细的例子看下面的:
```Go
{{with $x := "output" | printf "%q"}}{{$x}}{{end}} {{with $x := "output" | printf "%q"}}{{$x}}{{end}}
{{with $x := "output"}}{{printf "%q" $x}}{{end}} {{with $x := "output"}}{{printf "%q" $x}}{{end}}
{{with $x := "output"}}{{$x | printf "%q"}}{{end}} {{with $x := "output"}}{{$x | printf "%q"}}{{end}}
```
### 模板函数 ### 模板函数
模板在输出对象的字段值时,采用了`fmt`包把对象转化成了字符串。但是有时候我们的需求可能不是这样的,例如有时候我们为了防止垃圾邮件发送者通过采集网页的方式来发送给我们的邮箱信息,我们希望把`@`替换成`at`例如:`astaxie at beego.me`,如果要实现这样的功能,我们就需要自定义函数来做这个功能。 模板在输出对象的字段值时,采用了`fmt`包把对象转化成了字符串。但是有时候我们的需求可能不是这样的,例如有时候我们为了防止垃圾邮件发送者通过采集网页的方式来发送给我们的邮箱信息,我们希望把`@`替换成`at`例如:`astaxie at beego.me`,如果要实现这样的功能,我们就需要自定义函数来做这个功能。
每一个模板函数都有一个唯一值的名字然后与一个Go函数关联通过如下的方式来关联 每一个模板函数都有一个唯一值的名字然后与一个Go函数关联通过如下的方式来关联
```Go
type FuncMap map[string]interface{} type FuncMap map[string]interface{}
```
例如如果我们想要的email函数的模板函数名是`emailDeal`它关联的Go函数名称是`EmailDealWith`,那么我们可以通过下面的方式来注册这个函数 例如如果我们想要的email函数的模板函数名是`emailDeal`它关联的Go函数名称是`EmailDealWith`,那么我们可以通过下面的方式来注册这个函数
```Go
t = t.Funcs(template.FuncMap{"emailDeal": EmailDealWith}) t = t.Funcs(template.FuncMap{"emailDeal": EmailDealWith})
```
`EmailDealWith`这个函数的参数和返回值定义如下: `EmailDealWith`这个函数的参数和返回值定义如下:
```Go
func EmailDealWith(args interface{}) string func EmailDealWith(args interface{}) string
```
我们来看下面的实现例子: 我们来看下面的实现例子:
```Go
package main package main
@@ -230,8 +245,9 @@ Unix用户已经很熟悉什么是`pipe`了,`ls | grep "beego"`类似这样的
t.Execute(os.Stdout, p) t.Execute(os.Stdout, p)
} }
```
上面演示了如何自定义函数,其实,在模板包内部已经有内置的实现函数,下面代码截取自模板包里面 上面演示了如何自定义函数,其实,在模板包内部已经有内置的实现函数,下面代码截取自模板包里面
```Go
var builtins = FuncMap{ var builtins = FuncMap{
"and": and, "and": and,
@@ -248,9 +264,10 @@ Unix用户已经很熟悉什么是`pipe`了,`ls | grep "beego"`类似这样的
"urlquery": URLQueryEscaper, "urlquery": URLQueryEscaper,
} }
```
## Must操作 ## Must操作
模板包里面有一个函数`Must`它的作用是检测模板是否正确例如大括号是否匹配注释是否正确的关闭变量是否正确的书写。接下来我们演示一个例子用Must来判断模板是否正确 模板包里面有一个函数`Must`它的作用是检测模板是否正确例如大括号是否匹配注释是否正确的关闭变量是否正确的书写。接下来我们演示一个例子用Must来判断模板是否正确
```Go
package main package main
@@ -272,23 +289,29 @@ Unix用户已经很熟悉什么是`pipe`了,`ls | grep "beego"`类似这样的
template.Must(tErr.Parse(" some static text {{ .Name }")) template.Must(tErr.Parse(" some static text {{ .Name }"))
} }
```
将输出如下内容 将输出如下内容
```
The first one parsed OK. The first one parsed OK.
The second one parsed OK. The second one parsed OK.
The next one ought to fail. The next one ought to fail.
panic: template: check parse error with Must:1: unexpected "}" in command panic: template: check parse error with Must:1: unexpected "}" in command
```
## 嵌套模板 ## 嵌套模板
我们平常开发Web应用的时候经常会遇到一些模板有些部分是固定不变的然后可以抽取出来作为一个独立的部分例如一个博客的头部和尾部是不变的而唯一改变的是中间的内容部分。所以我们可以定义成`header``content``footer`三个部分。Go语言中通过如下的语法来申明 我们平常开发Web应用的时候经常会遇到一些模板有些部分是固定不变的然后可以抽取出来作为一个独立的部分例如一个博客的头部和尾部是不变的而唯一改变的是中间的内容部分。所以我们可以定义成`header``content``footer`三个部分。Go语言中通过如下的语法来申明
```Go
{{define "子模板名称"}}内容{{end}} {{define "子模板名称"}}内容{{end}}
```
通过如下方式来调用: 通过如下方式来调用:
```Go
{{template "子模板名称"}} {{template "子模板名称"}}
```
接下来我们演示如何使用嵌套模板,我们定义三个文件,`header.tmpl``content.tmpl``footer.tmpl`文件,里面的内容如下 接下来我们演示如何使用嵌套模板,我们定义三个文件,`header.tmpl``content.tmpl``footer.tmpl`文件,里面的内容如下
```html
//header.tmpl //header.tmpl
{{define "header"}} {{define "header"}}
@@ -315,8 +338,9 @@ Unix用户已经很熟悉什么是`pipe`了,`ls | grep "beego"`类似这样的
</body> </body>
</html> </html>
{{end}} {{end}}
```
演示代码如下: 演示代码如下:
```Go
package main package main
@@ -336,7 +360,7 @@ Unix用户已经很熟悉什么是`pipe`了,`ls | grep "beego"`类似这样的
fmt.Println() fmt.Println()
s1.Execute(os.Stdout, nil) s1.Execute(os.Stdout, nil)
} }
```
通过上面的例子我们可以看到通过`template.ParseFiles`把所有的嵌套模板全部解析到模板里面,其实每一个定义的{{define}}都是一个独立的模板他们相互独立是并行存在的关系内部其实存储的是类似map的一种关系(key是模板的名称value是模板的内容),然后我们通过`ExecuteTemplate`来执行相应的子模板内容我们可以看到header、footer都是相对独立的都能输出内容content 中因为嵌套了header和footer的内容就会同时输出三个的内容。但是当我们执行`s1.Execute`,没有任何的输出,因为在默认的情况下没有默认的子模板,所以不会输出任何的东西。 通过上面的例子我们可以看到通过`template.ParseFiles`把所有的嵌套模板全部解析到模板里面,其实每一个定义的{{define}}都是一个独立的模板他们相互独立是并行存在的关系内部其实存储的是类似map的一种关系(key是模板的名称value是模板的内容),然后我们通过`ExecuteTemplate`来执行相应的子模板内容我们可以看到header、footer都是相对独立的都能输出内容content 中因为嵌套了header和footer的内容就会同时输出三个的内容。但是当我们执行`s1.Execute`,没有任何的输出,因为在默认的情况下没有默认的子模板,所以不会输出任何的东西。
>同一个集合类的模板是互相知晓的,如果同一模板被多个集合使用,则它需要在多个集合中分别解析 >同一个集合类的模板是互相知晓的,如果同一模板被多个集合使用,则它需要在多个集合中分别解析