template.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. package template
  2. import (
  3. "io"
  4. "net/http"
  5. "sync"
  6. )
  7. // IEngine interface, to be implemented for any templating engine added to the repository
  8. type IEngine interface {
  9. IEngineCore
  10. Load() error
  11. Render(out io.Writer, template string, binding interface{}, layout ...string) error
  12. }
  13. // IEngineCore interface
  14. type IEngineCore interface {
  15. AddFunc(name string, fn interface{}) IEngineCore
  16. AddFuncMap(m map[string]interface{}) IEngineCore
  17. Debug(enabled bool) IEngineCore
  18. Delims(left, right string) IEngineCore
  19. FuncMap() map[string]interface{}
  20. Layout(key string) IEngineCore
  21. Reload(enabled bool) IEngineCore
  22. PreRenderCheck() bool
  23. }
  24. // Engine engine struct
  25. type Engine struct {
  26. IEngineCore
  27. // delimiters
  28. Left string
  29. Right string
  30. // views folder
  31. Directory string
  32. // http.FileSystem supports embedded files
  33. FileSystem http.FileSystem
  34. // views extension
  35. Extension string
  36. // layout variable name that incapsulates the template
  37. LayoutName string
  38. // determines if the engine parsed all templates
  39. Loaded bool
  40. // reload on each render
  41. ShouldReload bool
  42. // debug prints the parsed templates
  43. Verbose bool
  44. // lock for funcmap and templates
  45. Mutex sync.RWMutex
  46. // template funcmap
  47. Funcmap map[string]interface{}
  48. }
  49. // AddFunc adds the function to the template's function map.
  50. // It is legal to overwrite elements of the default actions
  51. func (e *Engine) AddFunc(name string, fn interface{}) IEngineCore {
  52. e.Mutex.Lock()
  53. e.Funcmap[name] = fn
  54. e.Mutex.Unlock()
  55. return e
  56. }
  57. // AddFuncMap adds the functions from a map to the template's function map.
  58. // It is legal to overwrite elements of the default actions
  59. func (e *Engine) AddFuncMap(m map[string]interface{}) IEngineCore {
  60. e.Mutex.Lock()
  61. for name, fn := range m {
  62. e.Funcmap[name] = fn
  63. }
  64. e.Mutex.Unlock()
  65. return e
  66. }
  67. // Debug will print the parsed templates when Load is triggered.
  68. func (e *Engine) Debug(enabled bool) IEngineCore {
  69. e.Mutex.Lock()
  70. e.Verbose = enabled
  71. e.Mutex.Unlock()
  72. return e
  73. }
  74. // Delims sets the action delimiters to the specified strings, to be used in
  75. // templates. An empty delimiter stands for the
  76. // corresponding default: "{{" and "}}".
  77. func (e *Engine) Delims(left, right string) IEngineCore {
  78. e.Mutex.Lock()
  79. e.Left, e.Right = left, right
  80. e.Mutex.Unlock()
  81. return e
  82. }
  83. // FuncMap returns the template's function map.
  84. func (e *Engine) FuncMap() map[string]interface{} {
  85. return e.Funcmap
  86. }
  87. // Layout defines the variable name that will incapsulate the template
  88. func (e *Engine) Layout(key string) IEngineCore {
  89. e.Mutex.Lock()
  90. e.LayoutName = key
  91. e.Mutex.Unlock()
  92. return e
  93. }
  94. // Reload if set to true the templates are reloading on each render,
  95. // use it when you're in development and you don't want to restart
  96. // the application when you edit a template file.
  97. func (e *Engine) Reload(enabled bool) IEngineCore {
  98. e.Mutex.Lock()
  99. e.ShouldReload = enabled
  100. e.Mutex.Unlock()
  101. return e
  102. }
  103. // Check if the engine should reload the templates before rendering
  104. // Explicit Mute Unlock vs defer offers better performance
  105. func (e *Engine) PreRenderCheck() bool {
  106. e.Mutex.Lock()
  107. if !e.Loaded || e.ShouldReload {
  108. if e.ShouldReload {
  109. e.Loaded = false
  110. }
  111. e.Mutex.Unlock()
  112. return true
  113. }
  114. e.Mutex.Unlock()
  115. return false
  116. }