view.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. package view
  2. import (
  3. "fmt"
  4. "html/template"
  5. "io"
  6. "strings"
  7. "github.com/kataras/iris/v12/context"
  8. "github.com/kataras/golog"
  9. )
  10. type (
  11. // Engine is the interface for a compatible Iris view engine.
  12. // It's an alias of context.ViewEngine.
  13. Engine = context.ViewEngine
  14. // EngineFuncer is the interface for a compatible Iris view engine
  15. // which accepts builtin framework functions such as url, urlpath and tr.
  16. // It's an alias of context.ViewEngineFuncer.
  17. EngineFuncer = context.ViewEngineFuncer
  18. )
  19. // ErrNotExist reports whether a template was not found in the parsed templates tree.
  20. type ErrNotExist = context.ErrViewNotExist
  21. // View is just a wrapper on top of the registered template engine.
  22. type View struct{ Engine }
  23. // Register registers a view engine.
  24. func (v *View) Register(e Engine) {
  25. if v.Engine != nil {
  26. golog.Warnf("Engine already exists, replacing the old %q with the new one %q", v.Engine.Name(), e.Name())
  27. }
  28. v.Engine = e
  29. }
  30. // Registered reports whether an engine was registered.
  31. func (v *View) Registered() bool {
  32. return v.Engine != nil
  33. }
  34. func (v *View) ensureTemplateName(s string) string {
  35. if s == "" || s == NoLayout {
  36. return s
  37. }
  38. s = strings.TrimPrefix(s, "/")
  39. if ext := v.Engine.Ext(); ext != "" {
  40. if !strings.HasSuffix(s, ext) {
  41. return s + ext
  42. }
  43. }
  44. return s
  45. }
  46. // ExecuteWriter calls the correct view Engine's ExecuteWriter func
  47. func (v *View) ExecuteWriter(w io.Writer, filename string, layout string, bindingData interface{}) error {
  48. filename = v.ensureTemplateName(filename)
  49. layout = v.ensureTemplateName(layout)
  50. return v.Engine.ExecuteWriter(w, filename, layout, bindingData)
  51. }
  52. // AddFunc adds a function to all registered engines.
  53. // Each template engine that supports functions has its own AddFunc too.
  54. func (v *View) AddFunc(funcName string, funcBody interface{}) {
  55. if !v.Registered() {
  56. return
  57. }
  58. if e, ok := v.Engine.(EngineFuncer); ok {
  59. e.AddFunc(funcName, funcBody)
  60. }
  61. }
  62. // Funcs registers a template func map to the registered view engine(s).
  63. func (v *View) Funcs(m template.FuncMap) *View {
  64. if !v.Registered() {
  65. return v
  66. }
  67. if e, ok := v.Engine.(EngineFuncer); ok {
  68. for k, v := range m {
  69. e.AddFunc(k, v)
  70. }
  71. }
  72. return v
  73. }
  74. // Load compiles all the registered engines.
  75. func (v *View) Load() error {
  76. if !v.Registered() {
  77. return fmt.Errorf("no engine was registered")
  78. }
  79. return v.Engine.Load()
  80. }
  81. // NoLayout disables the configuration's layout for a specific execution.
  82. const NoLayout = "iris.nolayout"
  83. // returns empty if it's no layout or empty layout and empty configuration's layout.
  84. func getLayout(layout string, globalLayout string) string {
  85. if layout == NoLayout {
  86. return ""
  87. }
  88. if layout == "" && globalLayout != "" {
  89. return globalLayout
  90. }
  91. return layout
  92. }