用于创建Render类型的函数。它接受Options类型的参数,返回一个Render类型。
我们一般通常不传入Options类型变量调用renderer.New()来创建一个Render类型。
var opt Options
if opts != nil {
opt = opts[0]
}
r := &Render{
opts: opt,
templates: make(map[string]*template.Template),
}
上面这段代码实际上就是初始化了一个Render类型的r变量。opts为nil, templates为map类型,这里被初始化。
接下来调用r.buildOptions()方法。
buildOptions方法
func (r *Render) buildOptions() {
if r.opts.Charset == "" { // 没有指定编码方式,使用默认的编码方式UTF-8
r.opts.Charset = defaultCharSet
}
if r.opts.JSONPrefix == "" { // 没有指定JSON前缀,使用默认的
r.opts.JSONPrefix = defaultJSONPrefix
}
if r.opts.XMLPrefix == "" { // 没有指定XML前缀,使用默认XML前缀
r.opts.XMLPrefix = defaultXMLPrefix
}
if r.opts.TemplateExtension == "" { // 模版扩展名设置
r.opts.TemplateExtension = "." + defaultTemplateExt
} else {
r.opts.TemplateExtension = "." + r.opts.TemplateExtension
}
if r.opts.LayoutExtension == "" { // 布局扩展名设置
r.opts.LayoutExtension = "." + defaultLayoutExt
} else {
r.opts.LayoutExtension = "." + r.opts.LayoutExtension
}
if r.opts.LeftDelim == "" { // 模版变量左分割符设置
r.opts.LeftDelim = defaultTemplateLeftDelim
}
if r.opts.RightDelim == "" { // 模版变量右分割符设置
r.opts.RightDelim = defaultTemplateRightDelim
}
// 设置内容类型属性常量
r.opts.ContentJSON = ContentJSON
r.opts.ContentJSONP = ContentJSONP
r.opts.ContentXML = ContentXML
r.opts.ContentYAML = ContentYAML
r.opts.ContentHTML = ContentHTML
r.opts.ContentText = ContentText
r.opts.ContentBinary = ContentBinary
// 如果没有禁用编码集,那么就将内容类型后面添加字符集属性。
if !r.opts.DisableCharset {
r.enableCharset()
}
}
该方法构建Render的opts属性,并绑定默认的值。
我们看了New函数,得到了一个Render类型,接下来就是呈现具体类型的内容。我们以JSON为例,看看它怎么实现的。
JSON方法
如果没有renderer包,我们想要用Go语言发送JSON数据响应,我们的实现代码大致如下:
func DoSomething(w http.ResponseWriter, ...) {
// json from a variable v
jData, err := json.Marshal(v)
if err != nil {
panic(err)
return
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(200)
w.Write(jData)
}
原理很简单,首先从变量中解析出JSON, 然后发送Content-Type为application/json, 然后发送状态码, 最后将json序列发送出去。
那么我们再详细看看renderer中的JSON方法的实现:
func (r *Render) JSON(w http.ResponseWriter, status int, v interface{}) error {
w.Header().Set(ContentType, r.opts.ContentJSON)
w.WriteHeader(status)
bs, err := r.json(v)
if err != nil {
return err
}
if r.opts.JSONPrefix != "" {
w.Write([]byte(r.opts.JSONPrefix))
}
_, err = w.Write(bs)
return err
}










