golang轻量级快速响应JSON/XML/HTML渲染插件库renderer的使用

Golang轻量级快速响应JSON/XML/HTML渲染插件库renderer的使用

安装

使用以下命令安装包:

$ go get github.com/thedevsaddam/renderer/...

使用

要在代码中使用这个包,请导入:

import "github.com/thedevsaddam/renderer"

示例

下面是一个完整的示例,展示如何使用renderer库来处理各种响应类型:

package main

import (
	"io"
	"log"
	"net/http"
	"os"

	"github.com/thedevsaddam/renderer"
)

func main() {
	rnd := renderer.New()

	mux := http.NewServeMux()

	usr := struct {
		Name string
		Age  int
	}{"John Doe", 30}

	// 以text/plain形式提供字符串
	mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		rnd.String(w, http.StatusOK, "Welcome to renderer")
	})

	// 成功响应但无内容
	mux.HandleFunc("/no-content", func(w http.ResponseWriter, r *http.Request) {
		rnd.NoContent(w)
	})

	// 以HTML形式提供字符串
	mux.HandleFunc("/html-string", func(w http.ResponseWriter, r *http.Request) {
		rnd.HTMLString(w, http.StatusOK, "<h1>Hello Renderer!</h1>")
	})

	// 提供JSON
	mux.HandleFunc("/json", func(w http.ResponseWriter, r *http.Request) {
		rnd.JSON(w, http.StatusOK, usr)
	})

	// 提供JSONP
	mux.HandleFunc("/jsonp", func(w http.ResponseWriter, r *http.Request) {
		rnd.JSONP(w, http.StatusOK, "callback", usr)
	})

	// 提供XML
	mux.HandleFunc("/xml", func(w http.ResponseWriter, r *http.Request) {
		rnd.XML(w, http.StatusOK, usr)
	})

	// 提供YAML
	mux.HandleFunc("/yaml", func(w http.ResponseWriter, r *http.Request) {
		rnd.YAML(w, http.StatusOK, usr)
	})

	// 提供文件作为任意二进制数据
	mux.HandleFunc("/binary", func(w http.ResponseWriter, r *http.Request) {
		var reader io.Reader
		reader, _ = os.Open("../README.md")
		rnd.Binary(w, http.StatusOK, reader, "readme.md", true)
	})

	// 提供文件作为内联内容
	mux.HandleFunc("/file-inline", func(w http.ResponseWriter, r *http.Request) {
		rnd.FileView(w, http.StatusOK, "../README.md", "readme.md")
	})

	// 提供文件作为附件下载
	mux.HandleFunc("/file-download", func(w http.ResponseWriter, r *http.Request) {
		rnd.FileDownload(w, http.StatusOK, "../README.md", "readme.md")
	})

	// 从reader提供文件作为内联内容
	mux.HandleFunc("/file-reader", func(w http.ResponseWriter, r *http.Request) {
		var reader io.Reader
		reader, _ = os.Open("../README.md")
		rnd.File(w, http.StatusOK, reader, "readme.md", true)
	})

	// 使用render和链式方法提供自定义响应
	mux.HandleFunc("/render", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set(renderer.ContentType, renderer.ContentText)
		rnd.Render(w, http.StatusOK, []byte("Send the message as text response"))
	})

	port := ":9000"
	log.Println("Listening on port", port)
	http.ListenAndServe(port, mux)
}

如何渲染HTML模板?

你可以使用HTMLViewTemplate方法中的任何一种来解析HTML模板。这些方法都基于html/template包。

Template示例

你可以使用Template方法动态解析模板。可以轻松设置分隔符和注入FuncMap。

template/layout.tmpl

<html>
  <head>
    <title>{{ template "title" . }}</title>
  </head>
  <body>
    {{ template "content" . }}
  </body>
  {{ block "sidebar" .}}{{end}}
</html>

template/index.tmpl

{{ define "title" }}Home{{ end }}

{{ define "content" }}
  <h1>Hello, {{ .Name | toUpper }}</h1>
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
{{ end }}

template/partial.tmpl

{{define "sidebar"}}
  simple sidebar code
{{end}}

template.go

package main

import (
	"html/template"
	"log"
	"net/http"
	"strings"

	"github.com/thedevsaddam/renderer"
)

var rnd *renderer.Render

func init() {
	rnd = renderer.New()
}

func toUpper(s string) string {
	return strings.ToUpper(s)
}

func handler(w http.ResponseWriter, r *http.Request) {
	usr := struct {
		Name string
		Age  int
	}{"john doe", 30}

	tpls := []string{"template/layout.tmpl", "template/index.tmpl", "template/partial.tmpl"}
	rnd.FuncMap(template.FuncMap{
		"toUpper": toUpper,
	})
	err := rnd.Template(w, http.StatusOK, tpls, usr)
	if err != nil {
		log.Fatal(err) // 响应错误页面或消息
	}
}

func main() {
	http.HandleFunc("/", handler)
	log.Println("Listening port: 9000")
	http.ListenAndServe(":9000", nil)
}

HTML示例

使用HTML时,你可以使用pattern解析模板目录并按名称调用模板。

html/index.html

{{define "indexPage"}}
    <html>
    {{template "header"}}
    <body>
        <h3>Index</h3>
        <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit</p>
    </body>
    {{template "footer"}}
    </html>
{{end}}

html/header.html

{{define "header"}}
     <head>
         <title>Header</title>
         <h1>Header section</h1>
     </head>
{{end}}

html/footer.html

{{define "footer"}}
     <footer>Copyright &copy; 2020</footer>
{{end}}

html.go

package main

import (
	"log"
	"net/http"

	"github.com/thedevsaddam/renderer"
)

var rnd *renderer.Render

func init() {
	rnd = renderer.New(
		renderer.Options{
			ParseGlobPattern: "html/*.html",
		},
	)
}

func handler(w http.ResponseWriter, r *http.Request) {
	err := rnd.HTML(w, http.StatusOK, "indexPage", nil)
	if err != nil {
		log.Fatal(err)
	}
}

func main() {
	http.HandleFunc("/", handler)
	log.Println("Listening port: 9000")
	http.ListenAndServe(":9000", nil)
}

View示例

使用View解析模板时,你可以传递多个布局和模板。这里模板名称将是文件名。

view/base.lout

<html>
  <head>
     <title>{{block "title" .}} {{end}}</title>
  </head>
  <body>
    {{ template "content" . }}
  </body>
</html>

view/home.tpl

{{define "title"}}Home{{end}}
{{define "content"}}
<h3>Home page</h3>
    <ul>
        <li><a href="/">Home</a></li>
        <li><a href="/about">About Me</a></li>
    </ul>
    <p>
    Lorem ipsum dolor sit amet</p>
{{end}}

view/about.tpl

{{define "title"}}About Me{{end}}
{{define "content"}}
<h2>This is About me page.</h2>
<ul>
    Lorem ipsum dolor sit amet, consectetur adipisicing elit,
</ul>
<p><a href="/">Home</a></p>
{{end}}

view.go

package main

import (
	"log"
	"net/http"

	"github.com/thedevsaddam/renderer"
)

var rnd *renderer.Render

func init() {
	rnd = renderer.New(renderer.Options{
		TemplateDir: "view",
	})
}

func home(w http.ResponseWriter, r *http.Request) {
	err := rnd.View(w, http.StatusOK, "home", nil)
	if err != nil {
		log.Fatal(err)
	}
}

func about(w http.ResponseWriter, r *http.Request) {
	err := rnd.View(w, http.StatusOK, "about", nil)
	if err != nil {
		log.Fatal(err)
	}
}

func main() {
	http.HandleFunc("/", home)
	http.HandleFunc("/about", about)
	log.Println("Listening port: 9000\n / is root \n /about is about page")
	http.ListenAndServe(":9000", nil)
}

注意: 这是一个内置在go包之上的包装器,用于提供语法糖。


更多关于golang轻量级快速响应JSON/XML/HTML渲染插件库renderer的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang轻量级快速响应JSON/XML/HTML渲染插件库renderer的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Golang轻量级快速响应渲染库renderer使用指南

renderer是一个轻量级的Golang库,用于快速响应和渲染JSON、XML、HTML等格式的内容。它提供了简洁的API,可以很方便地集成到任何Golang web应用中。

安装

go get github.com/thedevsaddam/renderer

基本使用

初始化

package main

import (
	"net/http"
	
	"github.com/thedevsaddam/renderer"
)

var rnd *renderer.Render

func init() {
	opts := renderer.Options{
		ParseGlobPattern: "./templates/*.html", // 模板文件路径
	}
	
	rnd = renderer.New(opts)
}

func main() {
	mux := http.NewServeMux()
	mux.HandleFunc("/", home)
	
	http.ListenAndServe(":8080", mux)
}

渲染不同类型的内容

1. 渲染JSON

func jsonHandler(w http.ResponseWriter, r *http.Request) {
	data := map[string]interface{}{
		"name":    "John Doe",
		"age":     30,
		"isAdmin": true,
	}
	
	// 渲染JSON,默认状态码200
	rnd.JSON(w, http.StatusOK, data)
	
	// 或者使用更简洁的方式
	// rnd.JSON(w, 200, data)
}

2. 渲染XML

func xmlHandler(w http.ResponseWriter, r *http.Request) {
	data := struct {
		XMLName xml.Name `xml:"person"`
		Name    string   `xml:"name"`
		Age     int      `xml:"age"`
	}{
		Name: "Jane Smith",
		Age:  28,
	}
	
	rnd.XML(w, http.StatusOK, data)
}

3. 渲染HTML

首先创建一个模板文件 templates/home.html:

<!DOCTYPE html>
<html>
<head>
    <title>{{.Title}}</title>
</head>
<body>
    <h1>{{.Message}}</h1>
</body>
</html>

然后渲染:

func home(w http.ResponseWriter, r *http.Request) {
	data := map[string]interface{}{
		"Title":   "Home Page",
		"Message": "Welcome to our website!",
	}
	
	rnd.HTML(w, http.StatusOK, "home", data)
}

高级功能

自定义配置

func init() {
	opts := renderer.Options{
		ParseGlobPattern: "./templates/*.html", // HTML模板路径
		Layout:          "layout",             // 布局文件名
		Extensions:      []string{".html"},    // 模板扩展名
		Charset:         "UTF-8",              // 字符编码
		DisableCharset:  false,                // 是否禁用字符集
		IndentJSON:      true,                 // JSON是否缩进
		IndentXML:       true,                 // XML是否缩进
		PrefixXML:       []byte(""),           // XML前缀
	}
	
	rnd = renderer.New(opts)
}

错误处理

func errorHandler(w http.ResponseWriter, r *http.Request) {
	err := someOperation()
	if err != nil {
		rnd.JSON(w, http.StatusInternalServerError, map[string]string{
			"error": err.Error(),
		})
		return
	}
	
	// 正常处理
	rnd.JSON(w, http.StatusOK, map[string]string{"status": "success"})
}

自定义响应头

func customHeaderHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("X-Custom-Header", "some-value")
	
	data := map[string]string{"message": "custom header set"}
	rnd.JSON(w, http.StatusOK, data)
}

性能优化建议

  1. 预加载模板:在初始化时通过ParseGlobPatternParseFiles预加载所有模板
  2. 重用Render实例:创建全局的Render实例而不是每次请求都新建
  3. 禁用调试模式:在生产环境中确保不启用调试模式
  4. 合理使用缓存:对于不常变化的内容可以启用缓存

与其他框架集成

与Gin集成

package main

import (
	"github.com/gin-gonic/gin"
	"github.com/thedevsaddam/renderer"
)

var rnd *renderer.Render

func init() {
	rnd = renderer.New()
}

func main() {
	r := gin.Default()
	
	r.GET("/json", func(c *gin.Context) {
		data := map[string]interface{}{
			"message": "pong",
		}
		rnd.JSON(c.Writer, http.StatusOK, data)
	})
	
	r.Run(":8080")
}

与Echo集成

package main

import (
	"net/http"
	
	"github.com/labstack/echo/v4"
	"github.com/thedevsaddam/renderer"
)

var rnd *renderer.Render

func init() {
	rnd = renderer.New()
}

func main() {
	e := echo.New()
	
	e.GET("/json", func(c echo.Context) error {
		data := map[string]interface{}{
			"message": "pong",
		}
		return rnd.JSON(c.Response().Writer, http.StatusOK, data)
	})
	
	e.Start(":8080")
}

总结

renderer库提供了简单易用的API来处理各种内容类型的渲染,具有以下优点:

  1. 轻量级,不依赖其他大型框架
  2. 支持JSON、XML、HTML等多种格式
  3. 易于集成到现有项目中
  4. 灵活的配置选项
  5. 良好的性能表现

对于需要快速构建API或简单web应用的项目,renderer是一个值得考虑的选择。

回到顶部