Merge pull request #962 from gin-gonic/feat/func-maps
Made funMaps for the templates configurable and hot-reloadable
This commit is contained in:
commit
54fe9df889
1
fixtures/basic/raw.tmpl
Normal file
1
fixtures/basic/raw.tmpl
Normal file
@ -0,0 +1 @@
|
||||
Date: {[{.now | formatAsDate}]}
|
18
gin.go
18
gin.go
@ -47,6 +47,7 @@ type (
|
||||
RouterGroup
|
||||
delims render.Delims
|
||||
HTMLRender render.HTMLRender
|
||||
FuncMap template.FuncMap
|
||||
allNoRoute HandlersChain
|
||||
allNoMethod HandlersChain
|
||||
noRoute HandlersChain
|
||||
@ -112,6 +113,7 @@ func New() *Engine {
|
||||
basePath: "/",
|
||||
root: true,
|
||||
},
|
||||
FuncMap: template.FuncMap{},
|
||||
RedirectTrailingSlash: true,
|
||||
RedirectFixedPath: false,
|
||||
HandleMethodNotAllowed: false,
|
||||
@ -147,19 +149,19 @@ func (engine *Engine) Delims(left, right string) *Engine {
|
||||
|
||||
func (engine *Engine) LoadHTMLGlob(pattern string) {
|
||||
if IsDebugging() {
|
||||
debugPrintLoadTemplate(template.Must(template.New("").Delims(engine.delims.Left, engine.delims.Right).ParseGlob(pattern)))
|
||||
engine.HTMLRender = render.HTMLDebug{Glob: pattern, Delims: engine.delims}
|
||||
debugPrintLoadTemplate(template.Must(template.New("").Delims(engine.delims.Left, engine.delims.Right).Funcs(engine.FuncMap).ParseGlob(pattern)))
|
||||
engine.HTMLRender = render.HTMLDebug{Glob: pattern, FuncMap: engine.FuncMap, Delims: engine.delims}
|
||||
} else {
|
||||
templ := template.Must(template.New("").Delims(engine.delims.Left, engine.delims.Right).ParseGlob(pattern))
|
||||
templ := template.Must(template.New("").Delims(engine.delims.Left, engine.delims.Right).Funcs(engine.FuncMap).ParseGlob(pattern))
|
||||
engine.SetHTMLTemplate(templ)
|
||||
}
|
||||
}
|
||||
|
||||
func (engine *Engine) LoadHTMLFiles(files ...string) {
|
||||
if IsDebugging() {
|
||||
engine.HTMLRender = render.HTMLDebug{Files: files, Delims: engine.delims}
|
||||
engine.HTMLRender = render.HTMLDebug{Files: files, FuncMap: engine.FuncMap, Delims: engine.delims}
|
||||
} else {
|
||||
templ := template.Must(template.New("").Delims(engine.delims.Left, engine.delims.Right).ParseFiles(files...))
|
||||
templ := template.Must(template.New("").Delims(engine.delims.Left, engine.delims.Right).Funcs(engine.FuncMap).ParseFiles(files...))
|
||||
engine.SetHTMLTemplate(templ)
|
||||
}
|
||||
}
|
||||
@ -169,7 +171,11 @@ func (engine *Engine) SetHTMLTemplate(templ *template.Template) {
|
||||
debugPrintWARNINGSetHTMLTemplate()
|
||||
}
|
||||
|
||||
engine.HTMLRender = render.HTMLProduction{Template: templ}
|
||||
engine.HTMLRender = render.HTMLProduction{Template: templ.Funcs(engine.FuncMap)}
|
||||
}
|
||||
|
||||
func (engine *Engine) SetFuncMap(funcMap template.FuncMap) {
|
||||
engine.FuncMap = funcMap
|
||||
}
|
||||
|
||||
// NoRoute adds handlers for NoRoute. It return a 404 code by default.
|
||||
|
54
gin_test.go
54
gin_test.go
@ -6,6 +6,7 @@ package gin
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"reflect"
|
||||
@ -15,14 +16,28 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func formatAsDate(t time.Time) string {
|
||||
year, month, day := t.Date()
|
||||
return fmt.Sprintf("%d/%02d/%02d", year, month, day)
|
||||
}
|
||||
|
||||
func setupHTMLFiles(t *testing.T) func() {
|
||||
go func() {
|
||||
SetMode(TestMode)
|
||||
router := New()
|
||||
router.Delims("{[{", "}]}")
|
||||
router.LoadHTMLFiles("./fixtures/basic/hello.tmpl")
|
||||
router.SetFuncMap(template.FuncMap{
|
||||
"formatAsDate": formatAsDate,
|
||||
})
|
||||
router.LoadHTMLFiles("./fixtures/basic/hello.tmpl", "./fixtures/basic/raw.tmpl")
|
||||
router.GET("/test", func(c *Context) {
|
||||
c.HTML(http.StatusOK, "hello.tmpl", map[string]string{"name": "world"})
|
||||
})
|
||||
router.GET("/raw", func(c *Context) {
|
||||
c.HTML(http.StatusOK, "raw.tmpl", map[string]interface{}{
|
||||
"now": time.Date(2017, 07, 01, 0, 0, 0, 0, time.UTC),
|
||||
})
|
||||
})
|
||||
router.Run(":8888")
|
||||
}()
|
||||
t.Log("waiting 1 second for server startup")
|
||||
@ -32,12 +47,21 @@ func setupHTMLFiles(t *testing.T) func() {
|
||||
|
||||
func setupHTMLGlob(t *testing.T) func() {
|
||||
go func() {
|
||||
SetMode(DebugMode)
|
||||
router := New()
|
||||
router.Delims("{[{", "}]}")
|
||||
router.SetFuncMap(template.FuncMap{
|
||||
"formatAsDate": formatAsDate,
|
||||
})
|
||||
router.LoadHTMLGlob("./fixtures/basic/*")
|
||||
router.GET("/test", func(c *Context) {
|
||||
c.HTML(http.StatusOK, "hello.tmpl", map[string]string{"name": "world"})
|
||||
})
|
||||
router.GET("/raw", func(c *Context) {
|
||||
c.HTML(http.StatusOK, "raw.tmpl", map[string]interface{}{
|
||||
"now": time.Date(2017, 07, 01, 0, 0, 0, 0, time.UTC),
|
||||
})
|
||||
})
|
||||
router.Run(":8888")
|
||||
}()
|
||||
t.Log("waiting 1 second for server startup")
|
||||
@ -59,6 +83,20 @@ func TestLoadHTMLGlob(t *testing.T) {
|
||||
td()
|
||||
}
|
||||
|
||||
func TestLoadHTMLGlobFromFuncMap(t *testing.T) {
|
||||
time.Now()
|
||||
td := setupHTMLGlob(t)
|
||||
res, err := http.Get("http://127.0.0.1:8888/raw")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
resp, _ := ioutil.ReadAll(res.Body)
|
||||
assert.Equal(t, "Date: 2017/07/01\n", string(resp[:]))
|
||||
|
||||
td()
|
||||
}
|
||||
|
||||
// func (engine *Engine) LoadHTMLFiles(files ...string) {
|
||||
// func (engine *Engine) RunTLS(addr string, cert string, key string) error {
|
||||
|
||||
@ -100,6 +138,20 @@ func TestLoadHTMLFiles(t *testing.T) {
|
||||
td()
|
||||
}
|
||||
|
||||
func TestLoadHTMLFilesFuncMap(t *testing.T) {
|
||||
time.Now()
|
||||
td := setupHTMLFiles(t)
|
||||
res, err := http.Get("http://127.0.0.1:8888/raw")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
resp, _ := ioutil.ReadAll(res.Body)
|
||||
assert.Equal(t, "Date: 2017/07/01\n", string(resp[:]))
|
||||
|
||||
td()
|
||||
}
|
||||
|
||||
func TestLoadHTMLReleaseMode(t *testing.T) {
|
||||
|
||||
}
|
||||
|
@ -25,9 +25,10 @@ type (
|
||||
}
|
||||
|
||||
HTMLDebug struct {
|
||||
Files []string
|
||||
Glob string
|
||||
Delims Delims
|
||||
Files []string
|
||||
Glob string
|
||||
Delims Delims
|
||||
FuncMap template.FuncMap
|
||||
}
|
||||
|
||||
HTML struct {
|
||||
@ -55,11 +56,14 @@ func (r HTMLDebug) Instance(name string, data interface{}) Render {
|
||||
}
|
||||
}
|
||||
func (r HTMLDebug) loadTemplate() *template.Template {
|
||||
if r.FuncMap == nil {
|
||||
r.FuncMap = template.FuncMap{}
|
||||
}
|
||||
if len(r.Files) > 0 {
|
||||
return template.Must(template.New("").Delims(r.Delims.Left, r.Delims.Right).ParseFiles(r.Files...))
|
||||
return template.Must(template.New("").Delims(r.Delims.Left, r.Delims.Right).Funcs(r.FuncMap).ParseFiles(r.Files...))
|
||||
}
|
||||
if len(r.Glob) > 0 {
|
||||
return template.Must(template.New("").Delims(r.Delims.Left, r.Delims.Right).ParseGlob(r.Glob))
|
||||
return template.Must(template.New("").Delims(r.Delims.Left, r.Delims.Right).Funcs(r.FuncMap).ParseGlob(r.Glob))
|
||||
}
|
||||
panic("the HTML debug render was created without files or glob pattern")
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user