Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Made funMaps for the templates configurable and hot-reloadable #962

Merged
merged 3 commits into from
Jul 2, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions fixtures/basic/raw.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Date: {[{.now | formatAsDate}]}
18 changes: 12 additions & 6 deletions gin.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ type (
RouterGroup
delims render.Delims
HTMLRender render.HTMLRender
FuncMap template.FuncMap
allNoRoute HandlersChain
allNoMethod HandlersChain
noRoute HandlersChain
Expand Down Expand Up @@ -112,6 +113,7 @@ func New() *Engine {
basePath: "/",
root: true,
},
FuncMap: template.FuncMap{},
RedirectTrailingSlash: true,
RedirectFixedPath: false,
HandleMethodNotAllowed: false,
Expand Down Expand Up @@ -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)
}
}
Expand All @@ -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.
Expand Down
54 changes: 53 additions & 1 deletion gin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package gin

import (
"fmt"
"html/template"
"io/ioutil"
"net/http"
"reflect"
Expand All @@ -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")
Expand All @@ -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")
Expand All @@ -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 {

Expand Down Expand Up @@ -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) {

}
Expand Down
14 changes: 9 additions & 5 deletions render/html.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@ type (
}

HTMLDebug struct {
Files []string
Glob string
Delims Delims
Files []string
Glob string
Delims Delims
FuncMap template.FuncMap
}

HTML struct {
Expand Down Expand Up @@ -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")
}
Expand Down