(摘抄)GO语言中template的用法
When a web service responds with data or html pages, there is usually a lot of content that isstandard. Within that there needs to be modifications done based on the user and what has been requested. Templates are a way to merge generic text with more specific text. i.e. retain the content that is common in the template and then substitute the specific content as required.
In Go, we use the template package and methods like Parse, ParseFile, Execute to load a template from a string or file and then perform the merge. The content to merge is within a defined type and that has exported fields, i.e. fields within the struct that are used within the template have to start with a capital letter.
Typical usage of templates is within html code that is generated from the server side. We wouldopen a template file which has already been defined, then merge that with some data we have using template.Execute which writes out the merged data into the io.Writer which is the first parameter. In the case of web functions, the io.Writer instance is passed into the handler ashttp.ResponseWriter. Partial code
- func handler(w http.ResponseWriter, r *http.Request) {
- t := template.New("some template") //create a new template
- t, _ = t.ParseFiles("tmpl/welcome.html", nil) //open and parse a template text file
- user := GetCurrentlyLoggedInUser() //a method we have separately defined to get the value for a type
- t.Execute(w, user) //substitute fields in the template 't', with values from 'user' and write it out to 'w' which implements io.Writer
- }
复制代码
We should be seeing other examples of actual html code which utilizes this functionality. But for the purposes of learning, to write out all that html is unnecessary clutter. So for learning purposes, we shall use simpler code where I can illustrate the template concepts more clearly. * Instead of template.ParseFiles to which we have to pass one or more file paths, I shall usetemplate.Parse for which I can give the text string directly in the code where it would be easier for you to see. * Instead of writing it as a web service, we shall write code we can execute from the commandline * We shall use the predefined variable os.Stdout which refers to the standard output to print out the merged data - os.Stdout implements io.Writer Field substitution - {{.FieldName}}To include the content of a field within a template, enclose it within curly braces and add a dot at the beginning. E.g. if Name is a field within a struct and its value needs to be substituted while merging, then include the text {{.Name}} in the template. Do remember that the field name has to be present and it should also be exported (i.e. it should begin with a capital letter in the type definition), or there could be errors. Full program
- package main
- import (
- "os"
- "text/template"
- )
- type Person struct {
- Name string //exported field since it begins with a capital letter
- }
- func main() {
- t := template.New(“hello template”) //create a new template with some name
- t, _ = t.Parse("hello {{.Name}}!") //parse some content and generate a template, which is an internal representation
- p := Person{Name:"Mary"} //define an instance with required field
- t.Execute(os.Stdout, p) //merge template ‘t’ with content of ‘p’
- }
复制代码
hello Mary! For the sake of completeness, let’s do an example where there is an error due to a missing field. In the below code, we have a field nonExportedAgeField, which, since it starts with a small letter, is not exported. Therefore when merging there is an error. You can check for the error on the return value of the Execute function. Full program
- package main
- import (
- "os"
- "text/template"
- "fmt"
- )
- type Person struct {
- Name string
- nonExportedAgeField string //because it doesn't start with a capital letter
- }
- func main() {
- p:= Person{Name: "Mary", nonExportedAgeField: "31"}
- t := template.New("nonexported template demo")
- t, _ = t.Parse("hello {{.Name}}! Age is {{.nonExportedAgeField}}.")
- err := t.Execute(os.Stdout, p)
- if err != nil {
- fmt.Println("There was an error:", err.String())
- }
- }
复制代码
hello Mary! Age is There was an error: template: nonexported template demo:1: can't evaluate field nonExportedAgeField in type main.Person template Must function - to check validity of template textThe static Must function checks for the validity of the template content, i.e. things like whether the braces are matches, whether comments are closed, and whether variables are properly formed, etc. In the example below, we have two valid template texts and they parse without causing a panic. The third one, however, has an unmatched brace and will panic. Full program
package main
import (
"text/template"
"fmt"
)
func main() {
tOk := template.New("first")
template.Must(tOk.Parse(" some static text /* and a comment */")) //a valid template, so no panic with Must
fmt.Println("The first one parsed OK.")
template.Must(template.New("second").Parse("some static text {{ .Name }}"))
fmt.Println("The second one parsed OK.")
fmt.Println("The next one ought to fail.")
tErr := template.New("check parse error with Must")
template.Must(tErr.Parse(" some static text {{ .Name }")) // due to unmatched brace, there should be a panic here
}
复制代码
The first one parsed OK. The second one parsed OK. The next one ought to fail. panic: template: check parse error with Must:1: unexpected "}" in command runtime.panic+0xac ... 说明:以上内容摘抄自:http://golangtutorials.blogspot.com/2011/06/go-templates.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 5分钟Flink - 流处理API转换算子集合
- 视频上云/网络穿透/网络映射服务EasyNTS前端组织添加页面出现Vue冲突怎么解决?
- Pinpoint 一款强大的APM工具
- 1. Pandas系列 - 基本数据结构
- 6 年前,只会 JSP 和 Servlet 就可以找到工作
- Python文件处理实用指南
- 2. Pandas系列 - Series基本功能
- 1.3 广告算法专题 - 交叉验证
- 最好用的内网穿透工具合集
- JVM垃圾回收之垃圾回收器,程序员必须掌握的知识
- 5分钟Flink - 时间与语义案例详解
- 5分钟Flink - 时间语义和Watermark
- 3. Pandas系列 - DataFrame操作
- 4. Pandas系列 - 基本功能和统计操作
- 面经手册 · 第8篇《LinkedList插入速度比ArrayList快?你确定吗?》