gview.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. // Copyright 2017 gf Author(https://github.com/gogf/gf). All Rights Reserved.
  2. //
  3. // This Source Code Form is subject to the terms of the MIT License.
  4. // If a copy of the MIT was not distributed with this file,
  5. // You can obtain one at https://github.com/gogf/gf.
  6. // Package gview implements a template engine based on text/template.
  7. //
  8. // Reserved template variable names:
  9. // I18nLanguage: Assign this variable to define i18n language for each page.
  10. package gview
  11. import (
  12. "github.com/gogf/gf/container/gmap"
  13. "github.com/gogf/gf/internal/intlog"
  14. "github.com/gogf/gf"
  15. "github.com/gogf/gf/container/garray"
  16. "github.com/gogf/gf/os/gcmd"
  17. "github.com/gogf/gf/os/gfile"
  18. "github.com/gogf/gf/os/glog"
  19. )
  20. // View object for template engine.
  21. type View struct {
  22. paths *garray.StrArray // Searching array for path, NOT concurrent-safe for performance purpose.
  23. data map[string]interface{} // Global template variables.
  24. funcMap map[string]interface{} // Global template function map.
  25. fileCacheMap *gmap.StrAnyMap // File cache map.
  26. config Config // Extra configuration for the view.
  27. }
  28. type (
  29. Params = map[string]interface{} // Params is type for template params.
  30. FuncMap = map[string]interface{} // FuncMap is type for custom template functions.
  31. )
  32. var (
  33. // Default view object.
  34. defaultViewObj *View
  35. )
  36. // checkAndInitDefaultView checks and initializes the default view object.
  37. // The default view object will be initialized just once.
  38. func checkAndInitDefaultView() {
  39. if defaultViewObj == nil {
  40. defaultViewObj = New()
  41. }
  42. }
  43. // ParseContent parses the template content directly using the default view object
  44. // and returns the parsed content.
  45. func ParseContent(content string, params ...Params) (string, error) {
  46. checkAndInitDefaultView()
  47. return defaultViewObj.ParseContent(content, params...)
  48. }
  49. // New returns a new view object.
  50. // The parameter <path> specifies the template directory path to load template files.
  51. func New(path ...string) *View {
  52. view := &View{
  53. paths: garray.NewStrArray(),
  54. data: make(map[string]interface{}),
  55. funcMap: make(map[string]interface{}),
  56. fileCacheMap: gmap.NewStrAnyMap(true),
  57. config: DefaultConfig(),
  58. }
  59. if len(path) > 0 && len(path[0]) > 0 {
  60. if err := view.SetPath(path[0]); err != nil {
  61. intlog.Error(err)
  62. }
  63. } else {
  64. // Customized dir path from env/cmd.
  65. if envPath := gcmd.GetWithEnv("gf.gview.path").String(); envPath != "" {
  66. if gfile.Exists(envPath) {
  67. if err := view.SetPath(envPath); err != nil {
  68. intlog.Error(err)
  69. }
  70. } else {
  71. if errorPrint() {
  72. glog.Errorf("Template directory path does not exist: %s", envPath)
  73. }
  74. }
  75. } else {
  76. // Dir path of working dir.
  77. if err := view.SetPath(gfile.Pwd()); err != nil {
  78. intlog.Error(err)
  79. }
  80. // Dir path of binary.
  81. if selfPath := gfile.SelfDir(); selfPath != "" && gfile.Exists(selfPath) {
  82. if err := view.AddPath(selfPath); err != nil {
  83. intlog.Error(err)
  84. }
  85. }
  86. // Dir path of main package.
  87. if mainPath := gfile.MainPkgPath(); mainPath != "" && gfile.Exists(mainPath) {
  88. if err := view.AddPath(mainPath); err != nil {
  89. intlog.Error(err)
  90. }
  91. }
  92. }
  93. }
  94. view.SetDelimiters("{{", "}}")
  95. // default build-in variables.
  96. view.data["GF"] = map[string]interface{}{
  97. "version": gf.VERSION,
  98. }
  99. // default build-in functions.
  100. view.BindFuncMap(FuncMap{
  101. "eq": view.buildInFuncEq,
  102. "ne": view.buildInFuncNe,
  103. "lt": view.buildInFuncLt,
  104. "le": view.buildInFuncLe,
  105. "gt": view.buildInFuncGt,
  106. "ge": view.buildInFuncGe,
  107. "text": view.buildInFuncText,
  108. "html": view.buildInFuncHtmlEncode,
  109. "htmlencode": view.buildInFuncHtmlEncode,
  110. "htmldecode": view.buildInFuncHtmlDecode,
  111. "encode": view.buildInFuncHtmlEncode,
  112. "decode": view.buildInFuncHtmlDecode,
  113. "url": view.buildInFuncUrlEncode,
  114. "urlencode": view.buildInFuncUrlEncode,
  115. "urldecode": view.buildInFuncUrlDecode,
  116. "date": view.buildInFuncDate,
  117. "substr": view.buildInFuncSubStr,
  118. "strlimit": view.buildInFuncStrLimit,
  119. "concat": view.buildInFuncConcat,
  120. "replace": view.buildInFuncReplace,
  121. "compare": view.buildInFuncCompare,
  122. "hidestr": view.buildInFuncHideStr,
  123. "highlight": view.buildInFuncHighlight,
  124. "toupper": view.buildInFuncToUpper,
  125. "tolower": view.buildInFuncToLower,
  126. "nl2br": view.buildInFuncNl2Br,
  127. "include": view.buildInFuncInclude,
  128. "dump": view.buildInFuncDump,
  129. "map": view.buildInFuncMap,
  130. "maps": view.buildInFuncMaps,
  131. "json": view.buildInFuncJson,
  132. })
  133. return view
  134. }