mirror of
https://github.com/gin-gonic/gin.git
synced 2025-10-20 00:02:16 +08:00
Add LoadHTMLGlobAppend
and LoadHTMLFilesAppend
to gin.Engine
Load new html templates to the exists HTMLRender. This method won't create a new template instance. So we can load templates from different path and use golang template `define` tag to give the templates proper name. Golang's `filepath.Glob` doesn't support glob dir recursively. This method may be helpful. May be related with #1296.
This commit is contained in:
parent
ffcbe77b1e
commit
7164a53b54
52
gin.go
52
gin.go
@ -180,7 +180,7 @@ func (engine *Engine) LoadHTMLGlob(pattern string) {
|
|||||||
|
|
||||||
if IsDebugging() {
|
if IsDebugging() {
|
||||||
debugPrintLoadTemplate(templ)
|
debugPrintLoadTemplate(templ)
|
||||||
engine.HTMLRender = render.HTMLDebug{Glob: pattern, FuncMap: engine.FuncMap, Delims: engine.delims}
|
engine.HTMLRender = &render.HTMLDebug{Globs: []string{pattern}, FuncMap: engine.FuncMap, Delims: engine.delims}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,7 +191,7 @@ func (engine *Engine) LoadHTMLGlob(pattern string) {
|
|||||||
// and associates the result with HTML renderer.
|
// and associates the result with HTML renderer.
|
||||||
func (engine *Engine) LoadHTMLFiles(files ...string) {
|
func (engine *Engine) LoadHTMLFiles(files ...string) {
|
||||||
if IsDebugging() {
|
if IsDebugging() {
|
||||||
engine.HTMLRender = render.HTMLDebug{Files: files, FuncMap: engine.FuncMap, Delims: engine.delims}
|
engine.HTMLRender = &render.HTMLDebug{Files: files, FuncMap: engine.FuncMap, Delims: engine.delims}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,13 +199,59 @@ func (engine *Engine) LoadHTMLFiles(files ...string) {
|
|||||||
engine.SetHTMLTemplate(templ)
|
engine.SetHTMLTemplate(templ)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// loadHTMLGlobAppend loads HTML files identified by a glob pattern
|
||||||
|
// and append the result to HTML renderer.
|
||||||
|
// loadHTMLGlobAppend will merge new files with previous template files.
|
||||||
|
// LoadHTMLGlob will forget old templates and create a new template object.
|
||||||
|
func (engine *Engine) loadHTMLGlobAppend(pattern string) {
|
||||||
|
if engine.HTMLRender == nil {
|
||||||
|
engine.LoadHTMLGlob(pattern)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if IsDebugging() {
|
||||||
|
left := engine.delims.Left
|
||||||
|
right := engine.delims.Right
|
||||||
|
templ := template.Must(template.New("").Delims(left, right).Funcs(engine.FuncMap).ParseGlob(pattern))
|
||||||
|
debugPrintLoadTemplate(templ)
|
||||||
|
}
|
||||||
|
|
||||||
|
engine.HTMLRender.ParseGlob(pattern)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadHTMLGlobAppend loads HTML files identified by glob patterns
|
||||||
|
// and append each result to HTML renderer.
|
||||||
|
// LoadHTMLGlobAppend will merge new files with previous template files.
|
||||||
|
// LoadHTMLGlob will forget old templates and create a new template object.
|
||||||
|
func (engine *Engine) LoadHTMLGlobAppend(patterns ...string) {
|
||||||
|
if len(patterns) <= 0 {
|
||||||
|
panic("LoadHTMLGlobAppend must have at least 1 arguments")
|
||||||
|
}
|
||||||
|
for _, pattern := range patterns {
|
||||||
|
engine.loadHTMLGlobAppend(pattern)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadHTMLFiles loads a slice of HTML files
|
||||||
|
// and append the result to HTML renderer.
|
||||||
|
// LoadHTMLFilesAppend will merge new files with previous template files.
|
||||||
|
// LoadHTMLFiles will forget old templates and create a new template object.
|
||||||
|
func (engine *Engine) LoadHTMLFilesAppend(files ...string) {
|
||||||
|
if engine.HTMLRender == nil {
|
||||||
|
engine.LoadHTMLFiles(files...)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
engine.HTMLRender.ParseFiles(files...)
|
||||||
|
}
|
||||||
|
|
||||||
// SetHTMLTemplate associate a template with HTML renderer.
|
// SetHTMLTemplate associate a template with HTML renderer.
|
||||||
func (engine *Engine) SetHTMLTemplate(templ *template.Template) {
|
func (engine *Engine) SetHTMLTemplate(templ *template.Template) {
|
||||||
if len(engine.trees) > 0 {
|
if len(engine.trees) > 0 {
|
||||||
debugPrintWARNINGSetHTMLTemplate()
|
debugPrintWARNINGSetHTMLTemplate()
|
||||||
}
|
}
|
||||||
|
|
||||||
engine.HTMLRender = render.HTMLProduction{Template: templ.Funcs(engine.FuncMap)}
|
engine.HTMLRender = &render.HTMLProduction{Template: templ.Funcs(engine.FuncMap)}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetFuncMap sets the FuncMap used for template.FuncMap.
|
// SetFuncMap sets the FuncMap used for template.FuncMap.
|
||||||
|
84
gin_test.go
84
gin_test.go
@ -118,6 +118,48 @@ func TestLoadHTMLGlobReleaseMode(t *testing.T) {
|
|||||||
assert.Equal(t, "<h1>Hello world</h1>", string(resp))
|
assert.Equal(t, "<h1>Hello world</h1>", string(resp))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestLoadHTMLGlobAppendDebugMode(t *testing.T) {
|
||||||
|
ts := setupHTMLFiles(
|
||||||
|
t,
|
||||||
|
DebugMode,
|
||||||
|
false,
|
||||||
|
func(router *Engine) {
|
||||||
|
router.LoadHTMLGlobAppend("./testdata/template/hello*")
|
||||||
|
router.LoadHTMLGlobAppend("./testdata/template/raw*")
|
||||||
|
},
|
||||||
|
)
|
||||||
|
defer ts.Close()
|
||||||
|
|
||||||
|
res, err := http.Get(fmt.Sprintf("%s/test", ts.URL))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, _ := ioutil.ReadAll(res.Body)
|
||||||
|
assert.Equal(t, "<h1>Hello world</h1>", string(resp))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLoadHTMLGlobAppendReleaseMode(t *testing.T) {
|
||||||
|
ts := setupHTMLFiles(
|
||||||
|
t,
|
||||||
|
ReleaseMode,
|
||||||
|
false,
|
||||||
|
func(router *Engine) {
|
||||||
|
router.LoadHTMLGlobAppend("./testdata/template/hello*")
|
||||||
|
router.LoadHTMLGlobAppend("./testdata/template/raw*")
|
||||||
|
},
|
||||||
|
)
|
||||||
|
defer ts.Close()
|
||||||
|
|
||||||
|
res, err := http.Get(fmt.Sprintf("%s/test", ts.URL))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, _ := ioutil.ReadAll(res.Body)
|
||||||
|
assert.Equal(t, "<h1>Hello world</h1>", string(resp))
|
||||||
|
}
|
||||||
|
|
||||||
func TestLoadHTMLGlobUsingTLS(t *testing.T) {
|
func TestLoadHTMLGlobUsingTLS(t *testing.T) {
|
||||||
ts := setupHTMLFiles(
|
ts := setupHTMLFiles(
|
||||||
t,
|
t,
|
||||||
@ -236,6 +278,48 @@ func TestLoadHTMLFilesReleaseMode(t *testing.T) {
|
|||||||
assert.Equal(t, "<h1>Hello world</h1>", string(resp))
|
assert.Equal(t, "<h1>Hello world</h1>", string(resp))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestLoadHTMLFilesAppendDebugMode(t *testing.T) {
|
||||||
|
ts := setupHTMLFiles(
|
||||||
|
t,
|
||||||
|
DebugMode,
|
||||||
|
false,
|
||||||
|
func(router *Engine) {
|
||||||
|
router.LoadHTMLFilesAppend("./testdata/template/raw.tmpl")
|
||||||
|
router.LoadHTMLFilesAppend("./testdata/template/hello.tmpl")
|
||||||
|
},
|
||||||
|
)
|
||||||
|
defer ts.Close()
|
||||||
|
|
||||||
|
res, err := http.Get(fmt.Sprintf("%s/test", ts.URL))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, _ := ioutil.ReadAll(res.Body)
|
||||||
|
assert.Equal(t, "<h1>Hello world</h1>", string(resp))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLoadHTMLFilesAppendReleaseMode(t *testing.T) {
|
||||||
|
ts := setupHTMLFiles(
|
||||||
|
t,
|
||||||
|
ReleaseMode,
|
||||||
|
false,
|
||||||
|
func(router *Engine) {
|
||||||
|
router.LoadHTMLFilesAppend("./testdata/template/raw.tmpl")
|
||||||
|
router.LoadHTMLFilesAppend("./testdata/template/hello.tmpl")
|
||||||
|
},
|
||||||
|
)
|
||||||
|
defer ts.Close()
|
||||||
|
|
||||||
|
res, err := http.Get(fmt.Sprintf("%s/test", ts.URL))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, _ := ioutil.ReadAll(res.Body)
|
||||||
|
assert.Equal(t, "<h1>Hello world</h1>", string(resp))
|
||||||
|
}
|
||||||
|
|
||||||
func TestLoadHTMLFilesUsingTLS(t *testing.T) {
|
func TestLoadHTMLFilesUsingTLS(t *testing.T) {
|
||||||
ts := setupHTMLFiles(
|
ts := setupHTMLFiles(
|
||||||
t,
|
t,
|
||||||
|
@ -21,6 +21,10 @@ type Delims struct {
|
|||||||
type HTMLRender interface {
|
type HTMLRender interface {
|
||||||
// Instance returns an HTML instance.
|
// Instance returns an HTML instance.
|
||||||
Instance(string, interface{}) Render
|
Instance(string, interface{}) Render
|
||||||
|
// Add new template files to this instance with glob
|
||||||
|
ParseGlob(pattern string)
|
||||||
|
// Add new template files to this instance
|
||||||
|
ParseFiles(files ...string)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTMLProduction contains template reference and its delims.
|
// HTMLProduction contains template reference and its delims.
|
||||||
@ -32,7 +36,7 @@ type HTMLProduction struct {
|
|||||||
// HTMLDebug contains template delims and pattern and function with file list.
|
// HTMLDebug contains template delims and pattern and function with file list.
|
||||||
type HTMLDebug struct {
|
type HTMLDebug struct {
|
||||||
Files []string
|
Files []string
|
||||||
Glob string
|
Globs []string
|
||||||
Delims Delims
|
Delims Delims
|
||||||
FuncMap template.FuncMap
|
FuncMap template.FuncMap
|
||||||
}
|
}
|
||||||
@ -55,6 +59,16 @@ func (r HTMLProduction) Instance(name string, data interface{}) Render {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add new template files to this instance (HTMLProduction) with glob
|
||||||
|
func (r *HTMLProduction) ParseGlob(pattern string) {
|
||||||
|
template.Must(r.Template.ParseGlob(pattern))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add new template files to this instance (HTMLProduction) with glob
|
||||||
|
func (r *HTMLProduction) ParseFiles(files ...string) {
|
||||||
|
template.Must(r.Template.ParseFiles(files...))
|
||||||
|
}
|
||||||
|
|
||||||
// Instance (HTMLDebug) returns an HTML instance which it realizes Render interface.
|
// Instance (HTMLDebug) returns an HTML instance which it realizes Render interface.
|
||||||
func (r HTMLDebug) Instance(name string, data interface{}) Render {
|
func (r HTMLDebug) Instance(name string, data interface{}) Render {
|
||||||
return HTML{
|
return HTML{
|
||||||
@ -63,17 +77,32 @@ func (r HTMLDebug) Instance(name string, data interface{}) Render {
|
|||||||
Data: data,
|
Data: data,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add new template files to this instance (HTMLProduction) with glob
|
||||||
|
func (r *HTMLDebug) ParseGlob(pattern string) {
|
||||||
|
r.Globs = append(r.Globs, pattern)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add new template files to this instance (HTMLDebug) with glob
|
||||||
|
func (r *HTMLDebug) ParseFiles(files ...string) {
|
||||||
|
r.Files = append(r.Files, files...)
|
||||||
|
}
|
||||||
|
|
||||||
func (r HTMLDebug) loadTemplate() *template.Template {
|
func (r HTMLDebug) loadTemplate() *template.Template {
|
||||||
if r.FuncMap == nil {
|
if r.FuncMap == nil {
|
||||||
r.FuncMap = template.FuncMap{}
|
r.FuncMap = template.FuncMap{}
|
||||||
}
|
}
|
||||||
if len(r.Files) > 0 {
|
if len(r.Files) == 0 && len(r.Globs) == 0 {
|
||||||
return template.Must(template.New("").Delims(r.Delims.Left, r.Delims.Right).Funcs(r.FuncMap).ParseFiles(r.Files...))
|
|
||||||
}
|
|
||||||
if 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")
|
panic("the HTML debug render was created without files or glob pattern")
|
||||||
|
}
|
||||||
|
t := template.New("").Delims(r.Delims.Left, r.Delims.Right).Funcs(r.FuncMap)
|
||||||
|
if len(r.Files) > 0 {
|
||||||
|
template.Must(t.ParseFiles(r.Files...))
|
||||||
|
}
|
||||||
|
for _, glob := range r.Globs {
|
||||||
|
template.Must(t.ParseGlob(glob))
|
||||||
|
}
|
||||||
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render (HTML) executes template and writes its result with custom ContentType for response.
|
// Render (HTML) executes template and writes its result with custom ContentType for response.
|
||||||
|
@ -24,8 +24,8 @@ var (
|
|||||||
_ Render = Redirect{}
|
_ Render = Redirect{}
|
||||||
_ Render = Data{}
|
_ Render = Data{}
|
||||||
_ Render = HTML{}
|
_ Render = HTML{}
|
||||||
_ HTMLRender = HTMLDebug{}
|
_ HTMLRender = &HTMLDebug{}
|
||||||
_ HTMLRender = HTMLProduction{}
|
_ HTMLRender = &HTMLProduction{}
|
||||||
_ Render = YAML{}
|
_ Render = YAML{}
|
||||||
_ Render = MsgPack{}
|
_ Render = MsgPack{}
|
||||||
_ Render = Reader{}
|
_ Render = Reader{}
|
||||||
|
@ -422,7 +422,7 @@ func TestRenderHTMLTemplateEmptyName(t *testing.T) {
|
|||||||
func TestRenderHTMLDebugFiles(t *testing.T) {
|
func TestRenderHTMLDebugFiles(t *testing.T) {
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
htmlRender := HTMLDebug{Files: []string{"../testdata/template/hello.tmpl"},
|
htmlRender := HTMLDebug{Files: []string{"../testdata/template/hello.tmpl"},
|
||||||
Glob: "",
|
Globs: []string{},
|
||||||
Delims: Delims{Left: "{[{", Right: "}]}"},
|
Delims: Delims{Left: "{[{", Right: "}]}"},
|
||||||
FuncMap: nil,
|
FuncMap: nil,
|
||||||
}
|
}
|
||||||
@ -440,7 +440,7 @@ func TestRenderHTMLDebugFiles(t *testing.T) {
|
|||||||
func TestRenderHTMLDebugGlob(t *testing.T) {
|
func TestRenderHTMLDebugGlob(t *testing.T) {
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
htmlRender := HTMLDebug{Files: nil,
|
htmlRender := HTMLDebug{Files: nil,
|
||||||
Glob: "../testdata/template/hello*",
|
Globs: []string{"../testdata/template/hello*"},
|
||||||
Delims: Delims{Left: "{[{", Right: "}]}"},
|
Delims: Delims{Left: "{[{", Right: "}]}"},
|
||||||
FuncMap: nil,
|
FuncMap: nil,
|
||||||
}
|
}
|
||||||
@ -457,7 +457,7 @@ func TestRenderHTMLDebugGlob(t *testing.T) {
|
|||||||
|
|
||||||
func TestRenderHTMLDebugPanics(t *testing.T) {
|
func TestRenderHTMLDebugPanics(t *testing.T) {
|
||||||
htmlRender := HTMLDebug{Files: nil,
|
htmlRender := HTMLDebug{Files: nil,
|
||||||
Glob: "",
|
Globs: []string{},
|
||||||
Delims: Delims{"{{", "}}"},
|
Delims: Delims{"{{", "}}"},
|
||||||
FuncMap: nil,
|
FuncMap: nil,
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user