golang轻松渲染JSON、XML和HTML模板响应插件库render的使用
Golang轻松渲染JSON、XML和HTML模板响应插件库Render的使用
Render是一个Go语言包,提供了轻松渲染JSON、XML、文本、二进制数据和HTML模板的功能。
基本用法
Render可以与任何能够访问http.ResponseWriter
的Web框架一起使用。渲染函数简单封装了Go现有的数据编组和渲染功能:
- HTML: 使用
html/template
包渲染HTML模板 - JSON: 使用
encoding/json
包将数据编组为JSON编码的响应 - XML: 使用
encoding/xml
包将数据编组为XML编码的响应 - 二进制数据: 将传入的数据直接传递到
http.ResponseWriter
- 文本: 将传入的字符串直接传递到
http.ResponseWriter
// main.go
package main
import (
"encoding/xml"
"net/http"
"github.com/unrolled/render"
)
type ExampleXml struct {
XMLName xml.Name `xml:"example"`
One string `xml:"one,attr"`
Two string `xml:"two,attr"`
}
func main() {
r := render.New()
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
w.Write([]byte("Welcome, visit sub pages now."))
})
mux.HandleFunc("/data", func(w http.ResponseWriter, req *http.Request) {
r.Data(w, http.StatusOK, []byte("Some binary data here."))
})
mux.HandleFunc("/text", func(w http.ResponseWriter, req *http.Request) {
r.Text(w, JSON、XML和HTML模板响应插件库Render的使用
## 基本用法
Render可以与任何能够访问`http.ResponseWriter`的Web框架一起使用。渲染函数简单封装了Go现有的数据编组和渲染功能:
- **HTML**: 使用`html/template`包渲染HTML模板
- **JSON**: 使用`encoding/json`包将数据编组为JSON编码的响应
- **XML**: 使用`encoding/xml`包将数据编组为XML编码的响应
- **二进制数据**: 将传入的数据直接传递到`http.ResponseWriter`
- **文本**: 将传入的字符串直接传递到`http.ResponseWriter`
```go
// main.go
package main
import (
"encoding/xml"
"net/http"
"github.com/unrolled/render"
)
type ExampleXml struct {
XMLName xml.Name `xml:"example"`
One string `xml:"one,attr"`
Two string `xml:"two,attr"`
}
func main() {
r := render.New()
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
w.Write([]byte("Welcome, visit sub pages now."))
})
mux.HandleFunc("/data", func(w http.ResponseWriter, req *http.Request) {
r.Data(w, http.StatusOK, []byte("Some binary data here."))
})
mux.HandleFunc("/text", func(w http.ResponseWriter, req *http.Request) {
r.Text(w, http.StatusOK, "Plain text here")
})
mux.HandleFunc("/json", func(w http.ResponseWriter, req *http.Request) {
r.JSON(w, http.StatusOK, map[string]string{"hello": "json"})
})
mux.HandleFunc("/jsonp", func(w http.ResponseWriter, req *http.Request) {
r.JSONP(w, http.StatusOK, "callbackName", map[string]string{"hello": "jsonp"})
})
mux.HandleFunc("/xml", func(w http.ResponseWriter, req *http.Request) {
r.XML(w, http.StatusOK, ExampleXml{One: "hello", Two: "xml"})
})
mux.HandleFunc("/html", func(w http.ResponseWriter, req *http.Request) {
// 假设你在./templates目录下有一个名为"example.tmpl"的模板
// $ mkdir -p templates && echo "<h1>Hello {{.}}.</h1>" > templates/example.tmpl
r.HTML(w, http.StatusOK, "example", "World")
})
http.ListenAndServe("127.0.0.1:3000", mux)
}
<!-- templates/example.tmpl -->
<h1>Hello {{.}}.</h1>
可用选项
Render提供了多种配置选项:
r := render.New(render.Options{
Directory: "templates", // 指定加载模板的路径
FileSystem: &LocalFileSystem{}, // 指定加载文件的文件系统
Asset: func(name string) ([]byte, error) { // 从Asset函数而不是文件加载
return []byte("template content"), nil
},
AssetNames: func() []string { // 返回Asset函数的资产名称列表
return []string{"filename.tmpl"}
},
Layout: "layout", // 指定布局模板
Extensions: []string{".tmpl", ".html"}, // 指定要加载的模板扩展名
Funcs: []template.FuncMap{AppHelpers}, // 指定模板可以访问的辅助函数映射
Delims: render.Delims{"{[{", "}]}"}, // 设置分隔符为指定字符串
Charset: "UTF-8", // 设置内容类型的编码
DisableCharset: true, // 防止字符集附加到内容类型头
IndentJSON: true, // 输出人类可读的JSON
IndentXML: true, // 输出人类可读的XML
PrefixJSON: []byte(")]}',\n"), // 用给定的字节前缀JSON响应
PrefixXML: []byte("<?xml version='1.0' encoding='UTF-8'?>"), // 用给定的字节前缀XML响应
HTMLContentType: "application/xhtml+xml", // 输出XHTML内容类型而不是默认的"text/html"
IsDevelopment: true, // 现在Render将在每个HTML响应上重新编译模板
UseMutexLock: true, // 覆盖默认的无锁实现并使用标准的`sync.RWMutex`锁
UnEscapeHTML: true, // 确保'&<>'正确输出(仅限JSON)
StreamingJSON: true, // 通过json.Encoder流式传输JSON响应
HTMLTemplateOption: "missingkey=error", // 设置HTML模板的选项值
RequirePartials: true, // 如果模板缺少布局中使用的部分,则返回错误
DisableHTTPErrorRendering: true, // 禁用发生错误时自动渲染http.StatusInternalServerError
JSONEncoder: func(w io.Writer) render.JSONEncoder { // 使用jsoniter "github.com/json-iterator"
return jsoniter.NewEncoder(w)
},
})
默认选项
这些是Render的预设选项:
r := render.New()
// 等同于默认配置选项:
r := render.New(render.Options{
Directory: "templates",
FileSystem: &LocalFileSystem{},
Asset: nil,
AssetNames: nil,
Layout: "",
Extensions: []string{".tmpl"},
Funcs: []template.FuncMap{},
Delims: render.Delims{"{{", "}}"},
Charset: "UTF-8",
DisableCharset: false,
IndentJSON: false,
IndentXML: false,
PrefixJSON: []byte(""),
PrefixXML: []byte(""),
BinaryContentType: "application/octet-stream",
HTMLContentType: "text/html",
JSONContentType: "application/json",
JSONPContentType: "application/javascript",
TextContentType: "text/plain",
XMLContentType: "application/xhtml+xml",
IsDevelopment: false,
UseMutexLock: false,
UnEscapeHTML: false,
HTMLTemplateOption: "",
StreamingJSON: false,
RequirePartials: false,
DisableHTTPErrorRendering: false,
RenderPartialsWithoutPrefix: false,
BufferPool: GenericBufferPool,
JSONEncoder: nil,
})
模板加载
默认情况下,Render将尝试从"templates"目录加载扩展名为’.tmpl’的模板。模板是通过遍历模板目录找到的,并按路径和基名命名。例如,以下目录结构:
templates/
|
|__ admin/
| |
| |__ index.tmpl
| |
| |__ edit.tmpl
|
|__ home.tmpl
将提供以下模板:
admin/index
admin/edit
home
布局
Render为布局提供了yield
和partial
函数:
r := render.New(render.Options{
Layout: "layout",
})
<!-- templates/layout.tmpl -->
<html>
<head>
<title>My Layout</title>
<!-- 在这里渲染名为`css-$current_template`的部分模板 -->
{{ partial "css" }}
</head>
<body>
<!-- 在这里渲染名为`header-$current_template`的部分模板 -->
{{ partial "header" }}
<!-- 在这里渲染当前模板 -->
{{ yield }}
<!-- 在这里渲染名为`footer-$current_template`的部分模板 -->
{{ partial "footer" }}
</body>
</html>
字符编码
Render会根据您调用的函数自动设置适当的Content-Type头。默认情况下,Render会使用UTF-8编码,二进制数据不会输出字符集。
错误处理
渲染函数会返回来自渲染引擎的任何错误。默认情况下,它们还会将错误写入HTTP响应并将状态代码设置为500。您可以通过设置Options.DisableHTTPErrorRendering: true
来禁用此行为,以便自己处理错误。
r := render.New(render.Options{
DisableHTTPErrorRendering: true,
})
err := r.HTML(w, http.StatusOK, "example", "World")
if err != nil{
http.Redirect(w, r, "/my-custom-500", http.StatusFound)
}
框架集成示例
Echo框架集成
// main.go
package main
import (
"io"
"net/http"
"github.com/labstack/echo"
"github.com/unrolled/render"
)
type RenderWrapper struct { // 我们需要包装渲染器,因为echo需要不同的签名
rnd *render.Render
}
func (r *RenderWrapper) Render(w io.Writer, name string, data interface{},c echo.Context) error {
return r.rnd.HTML(w, 0, name, data) // 零状态码会被echo覆盖
}
func main() {
r := &RenderWrapper{render.New()}
e := echo.New()
e.Renderer = r
e.GET("/", func(c echo.Context) error {
return c.Render(http.StatusOK, "TemplateName", "TemplateData")
})
e.Logger.Fatal(e.Start("127.0.0.1:8080"))
}
Gin框架集成
// main.go
package main
import (
"net/http"
"github.com/gin-gonic/gin"
"github.com/unrolled/render"
)
func main() {
r := render.New(render.Options{
IndentJSON: true,
})
router := gin.Default()
router.GET("/", func(c *gin.Context) {
r.JSON(c.Writer, http.StatusOK, map[string]string{"welcome": "This is rendered JSON!"})
})
router.Run("127.0.0.1:8080")
}
更多关于golang轻松渲染JSON、XML和HTML模板响应插件库render的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复