Skip to content

Commit

Permalink
Merge pull request devfeel#154 from devfeel/develop
Browse files Browse the repository at this point in the history
Version 1.5.7.6 - Add Renderer.RegisterTemplateFunc
  • Loading branch information
devfeel authored Sep 7, 2018
2 parents 2519e12 + 9d7aa34 commit 8d20036
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 11 deletions.
5 changes: 4 additions & 1 deletion example/render/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ func main() {
//设置dotserver日志目录
app.SetLogPath(file.GetCurrentDirectory())

//app.SetDevelopmentMode()
app.SetDevelopmentMode()

//设置gzip开关
//app.HttpServer.SetEnabledGzip(true)
Expand All @@ -24,6 +24,9 @@ func main() {

//set default template path
app.HttpServer.Renderer().SetTemplatePath("d:/gotmp/")
app.HttpServer.Renderer().RegisterTemplateFunc("echo", func(x string) interface{}{
return "echo:" + x
})

//启动 监控服务
//app.SetPProfConfig(true, 8081)
Expand Down
2 changes: 1 addition & 1 deletion example/render/testview.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ <h1>{{.data}}</h1>
<b>Books:</b>
<br>
{{range .Books}}
BookName => {{.Name}}; Size => {{.Size}}
BookName => {{echo .Name}}; Size => {{.Size}}
<br>
{{end}}
</div>
Expand Down
42 changes: 33 additions & 9 deletions render.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@ import (
"io"
"path"
"sync"
"path/filepath"
"errors"
)

// Renderer is the interface that wraps the render method.
type Renderer interface {
SetTemplatePath(path string)
Render(io.Writer, interface{}, Context, ...string) error
RegisterTemplateFunc(string, interface{})
}

type innerRenderer struct {
Expand All @@ -20,10 +23,18 @@ type innerRenderer struct {
enabledCache bool
templateCache map[string]*template.Template
templateCacheMutex sync.RWMutex

// used to manager template func
templateFuncs map[string]interface{}
templateFuncsMutex *sync.RWMutex

}

// Render render view use http/template
func (r *innerRenderer) Render(w io.Writer, data interface{}, ctx Context, tpl ...string) error {
if len(tpl) <= 0{
return errors.New("no enough render template files")
}
t, err := r.parseFiles(tpl...)
if err != nil {
return err
Expand All @@ -36,7 +47,15 @@ func (r *innerRenderer) SetTemplatePath(path string) {
r.templatePath = path
}

// 定义函数unescaped
// RegisterTemplateFunc used to register template func in renderer
func (r *innerRenderer) RegisterTemplateFunc(funcName string, funcHandler interface{}){
r.templateFuncsMutex.Lock()
r.templateFuncs[funcName] = funcHandler
r.templateFuncsMutex.Unlock()
}


// unescaped inner template func used to encapsulates a known safe HTML document fragment
func unescaped(x string) interface{} { return template.HTML(x) }

// return http/template by gived file name
Expand All @@ -59,7 +78,12 @@ func (r *innerRenderer) parseFiles(fileNames ...string) (*template.Template, err
t, exists = r.parseFilesFromCache(filesCacheKey)
}
if !exists{
t, err = template.ParseFiles(realFileNames...)
name := filepath.Base(fileNames[0])
t = template.New(name)
if len(r.templateFuncs) > 0{
t = t.Funcs(r.templateFuncs)
}
t, err = t.ParseFiles(realFileNames...)
if err != nil {
return nil, err
}
Expand All @@ -68,7 +92,6 @@ func (r *innerRenderer) parseFiles(fileNames ...string) (*template.Template, err
r.templateCache[filesCacheKey] = t
}

t = registeTemplateFunc(t)
return t, nil
}

Expand All @@ -79,25 +102,26 @@ func (r *innerRenderer) parseFilesFromCache(filesCacheKey string) (*template.Tem
return t, exists
}

// registeTemplateFunc registe default support funcs
func registeTemplateFunc(t *template.Template) *template.Template {
return t.Funcs(template.FuncMap{"unescaped": unescaped})
//TODO:add more func
// registeInnerTemplateFunc registe default support funcs
func registeInnerTemplateFunc(funcMap map[string]interface{}){
funcMap["unescaped"] = unescaped
}

// NewInnerRenderer create a inner renderer instance
func NewInnerRenderer() Renderer {
r := new(innerRenderer)
r.enabledCache = true
r.templateCache = make(map[string]*template.Template)
r.templateFuncs = make(map[string]interface{})
r.templateFuncsMutex = new(sync.RWMutex)
registeInnerTemplateFunc(r.templateFuncs)
return r
}

// NewInnerRendererNoCache create a inner renderer instance with no cache mode
func NewInnerRendererNoCache() Renderer {
r := new(innerRenderer)
r := NewInnerRenderer().(*innerRenderer)
r.enabledCache = false
r.templateCache = make(map[string]*template.Template)
return r
}

13 changes: 13 additions & 0 deletions version.MD
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
## dotweb版本记录:

#### Version 1.5.7.6
* New Feature: Add Renderer.RegisterTemplateFunc, used to register template func in renderer
* Detail:
- now inner support inner func like unescaped
- you can view example on example/render
* Example:
``` golang
app.HttpServer.Renderer().RegisterTemplateFunc("echo", func(x string) interface{}{
return "echo:" + x
})
```
* 2018-09-07

#### Version 1.5.7.5
* Fixed Bug: return err from Next() in RequestLogMiddleware & TimeoutHookMiddleware
* 2018-08-30 10:00
Expand Down

0 comments on commit 8d20036

Please sign in to comment.