mirror of https://github.com/gin-gonic/gin.git
Adds flexible render system
This commit is contained in:
parent
94bc35bb2d
commit
5ea7a92267
|
@ -31,3 +31,8 @@ func (c *Context) ParseBody(item interface{}) error {
|
||||||
func (engine *Engine) ServeFiles(path string, root http.FileSystem) {
|
func (engine *Engine) ServeFiles(path string, root http.FileSystem) {
|
||||||
engine.router.ServeFiles(path, root)
|
engine.router.ServeFiles(path, root)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DEPRECATED use gin.LoadHTMLGlob() or gin.LoadHTMLFiles() instead
|
||||||
|
func (engine *Engine) LoadHTMLTemplates(pattern string) {
|
||||||
|
engine.LoadHTMLGlob(pattern)
|
||||||
|
}
|
||||||
|
|
67
gin.go
67
gin.go
|
@ -2,11 +2,11 @@ package gin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/gin-gonic/gin/binding"
|
"github.com/gin-gonic/gin/binding"
|
||||||
|
"github.com/gin-gonic/gin/render"
|
||||||
"github.com/julienschmidt/httprouter"
|
"github.com/julienschmidt/httprouter"
|
||||||
"html/template"
|
"html/template"
|
||||||
"log"
|
"log"
|
||||||
|
@ -71,7 +71,7 @@ type (
|
||||||
// Represents the web framework, it wraps the blazing fast httprouter multiplexer and a list of global middlewares.
|
// Represents the web framework, it wraps the blazing fast httprouter multiplexer and a list of global middlewares.
|
||||||
Engine struct {
|
Engine struct {
|
||||||
*RouterGroup
|
*RouterGroup
|
||||||
HTMLTemplates *template.Template
|
HTMLRender render.Render
|
||||||
cache sync.Pool
|
cache sync.Pool
|
||||||
handlers404 []HandlerFunc
|
handlers404 []HandlerFunc
|
||||||
router *httprouter.Router
|
router *httprouter.Router
|
||||||
|
@ -147,8 +147,20 @@ func Default() *Engine {
|
||||||
return engine
|
return engine
|
||||||
}
|
}
|
||||||
|
|
||||||
func (engine *Engine) LoadHTMLTemplates(pattern string) {
|
func (engine *Engine) LoadHTMLGlob(pattern string) {
|
||||||
engine.HTMLTemplates = template.Must(template.ParseGlob(pattern))
|
templ := template.Must(template.ParseGlob(pattern))
|
||||||
|
engine.SetHTTPTemplate(templ)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (engine *Engine) LoadHTMLFiles(files ...string) {
|
||||||
|
templ := template.Must(template.ParseFiles(files...))
|
||||||
|
engine.SetHTTPTemplate(templ)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (engine *Engine) SetHTTPTemplate(templ *template.Template) {
|
||||||
|
engine.HTMLRender = render.HTMLRender{
|
||||||
|
Template: templ,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adds handlers for NotFound. It return a 404 code by default.
|
// Adds handlers for NotFound. It return a 404 code by default.
|
||||||
|
@ -441,58 +453,35 @@ func (c *Context) BindWith(obj interface{}, b binding.Binding) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Serializes the given struct as JSON into the response body in a fast and efficient way.
|
func (c *Context) Render(code int, render render.Render, obj ...interface{}) {
|
||||||
// It also sets the Content-Type as "application/json".
|
if err := render.Render(c.Writer, code, obj); err != nil {
|
||||||
func (c *Context) JSON(code int, obj interface{}) {
|
|
||||||
c.Writer.Header().Set("Content-Type", MIMEJSON)
|
|
||||||
if code >= 0 {
|
|
||||||
c.Writer.WriteHeader(code)
|
|
||||||
}
|
|
||||||
encoder := json.NewEncoder(c.Writer)
|
|
||||||
if err := encoder.Encode(obj); err != nil {
|
|
||||||
c.ErrorTyped(err, ErrorTypeInternal, obj)
|
c.ErrorTyped(err, ErrorTypeInternal, obj)
|
||||||
c.Abort(500)
|
c.Abort(500)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Serializes the given struct as JSON into the response body in a fast and efficient way.
|
||||||
|
// It also sets the Content-Type as "application/json".
|
||||||
|
func (c *Context) JSON(code int, obj interface{}) {
|
||||||
|
c.Render(code, render.JSON, obj)
|
||||||
|
}
|
||||||
|
|
||||||
// Serializes the given struct as XML into the response body in a fast and efficient way.
|
// Serializes the given struct as XML into the response body in a fast and efficient way.
|
||||||
// It also sets the Content-Type as "application/xml".
|
// It also sets the Content-Type as "application/xml".
|
||||||
func (c *Context) XML(code int, obj interface{}) {
|
func (c *Context) XML(code int, obj interface{}) {
|
||||||
c.Writer.Header().Set("Content-Type", MIMEXML)
|
c.Render(code, render.XML, obj)
|
||||||
if code >= 0 {
|
|
||||||
c.Writer.WriteHeader(code)
|
|
||||||
}
|
|
||||||
encoder := xml.NewEncoder(c.Writer)
|
|
||||||
if err := encoder.Encode(obj); err != nil {
|
|
||||||
c.ErrorTyped(err, ErrorTypeInternal, obj)
|
|
||||||
c.Abort(500)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Renders the HTTP template specified by its file name.
|
// Renders the HTTP template specified by its file name.
|
||||||
// It also updates the HTTP code and sets the Content-Type as "text/html".
|
// It also updates the HTTP code and sets the Content-Type as "text/html".
|
||||||
// See http://golang.org/doc/articles/wiki/
|
// See http://golang.org/doc/articles/wiki/
|
||||||
func (c *Context) HTML(code int, name string, data interface{}) {
|
func (c *Context) HTML(code int, name string, obj interface{}) {
|
||||||
c.Writer.Header().Set("Content-Type", MIMEHTML)
|
c.Render(code, c.Engine.HTMLRender, name, obj)
|
||||||
if code >= 0 {
|
|
||||||
c.Writer.WriteHeader(code)
|
|
||||||
}
|
|
||||||
if err := c.Engine.HTMLTemplates.ExecuteTemplate(c.Writer, name, data); err != nil {
|
|
||||||
c.ErrorTyped(err, ErrorTypeInternal, H{
|
|
||||||
"name": name,
|
|
||||||
"data": data,
|
|
||||||
})
|
|
||||||
c.Abort(500)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Writes the given string into the response body and sets the Content-Type to "text/plain".
|
// Writes the given string into the response body and sets the Content-Type to "text/plain".
|
||||||
func (c *Context) String(code int, format string, values ...interface{}) {
|
func (c *Context) String(code int, format string, values ...interface{}) {
|
||||||
c.Writer.Header().Set("Content-Type", MIMEPlain)
|
c.Render(code, render.Plain, format, values)
|
||||||
if code >= 0 {
|
|
||||||
c.Writer.WriteHeader(code)
|
|
||||||
}
|
|
||||||
c.Writer.Write([]byte(fmt.Sprintf(format, values...)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Writes some data into the body stream and updates the HTTP code.
|
// Writes some data into the body stream and updates the HTTP code.
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
package render
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"encoding/xml"
|
||||||
|
"fmt"
|
||||||
|
"html/template"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
Render interface {
|
||||||
|
Render(http.ResponseWriter, int, ...interface{}) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// JSON binding
|
||||||
|
jsonRender struct{}
|
||||||
|
|
||||||
|
// XML binding
|
||||||
|
xmlRender struct{}
|
||||||
|
|
||||||
|
// Plain text
|
||||||
|
plainRender struct{}
|
||||||
|
|
||||||
|
// form binding
|
||||||
|
HTMLRender struct {
|
||||||
|
Template *template.Template
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
JSON = jsonRender{}
|
||||||
|
XML = xmlRender{}
|
||||||
|
Plain = plainRender{}
|
||||||
|
)
|
||||||
|
|
||||||
|
func writeHeader(w http.ResponseWriter, code int, contentType string) {
|
||||||
|
if code >= 0 {
|
||||||
|
w.Header().Set("Content-Type", contentType)
|
||||||
|
w.WriteHeader(code)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ jsonRender) Render(w http.ResponseWriter, code int, data ...interface{}) error {
|
||||||
|
writeHeader(w, code, "application/xml")
|
||||||
|
encoder := json.NewEncoder(w)
|
||||||
|
return encoder.Encode(data[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ xmlRender) Render(w http.ResponseWriter, code int, data ...interface{}) error {
|
||||||
|
writeHeader(w, code, "application/xml")
|
||||||
|
encoder := xml.NewEncoder(w)
|
||||||
|
return encoder.Encode(data[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (html HTMLRender) Render(w http.ResponseWriter, code int, data ...interface{}) error {
|
||||||
|
writeHeader(w, code, "text/html")
|
||||||
|
file := data[0].(string)
|
||||||
|
obj := data[1]
|
||||||
|
return html.Template.ExecuteTemplate(w, file, obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_ plainRender) Render(w http.ResponseWriter, code int, data ...interface{}) error {
|
||||||
|
writeHeader(w, code, "text/plain")
|
||||||
|
format := data[0].(string)
|
||||||
|
args := data[1].([]interface{})
|
||||||
|
_, err := w.Write([]byte(fmt.Sprintf(format, args)))
|
||||||
|
return err
|
||||||
|
}
|
Loading…
Reference in New Issue