gview_buildin.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. // Copyright GoFrame Author(https://goframe.org). 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
  7. import (
  8. "bytes"
  9. "context"
  10. "fmt"
  11. htmltpl "html/template"
  12. "strings"
  13. "github.com/gogf/gf/v2/encoding/ghtml"
  14. "github.com/gogf/gf/v2/encoding/gjson"
  15. "github.com/gogf/gf/v2/encoding/gurl"
  16. "github.com/gogf/gf/v2/os/gtime"
  17. "github.com/gogf/gf/v2/text/gstr"
  18. "github.com/gogf/gf/v2/util/gconv"
  19. "github.com/gogf/gf/v2/util/gmode"
  20. "github.com/gogf/gf/v2/util/gutil"
  21. )
  22. // buildInFuncDump implements build-in template function: dump
  23. func (view *View) buildInFuncDump(values ...interface{}) string {
  24. buffer := bytes.NewBuffer(nil)
  25. buffer.WriteString("\n")
  26. buffer.WriteString("<!--\n")
  27. if gmode.IsDevelop() {
  28. for _, v := range values {
  29. gutil.DumpTo(buffer, v, gutil.DumpOption{})
  30. buffer.WriteString("\n")
  31. }
  32. } else {
  33. buffer.WriteString("dump feature is disabled as process is not running in develop mode\n")
  34. }
  35. buffer.WriteString("-->\n")
  36. return buffer.String()
  37. }
  38. // buildInFuncMap implements build-in template function: map
  39. func (view *View) buildInFuncMap(value ...interface{}) map[string]interface{} {
  40. if len(value) > 0 {
  41. return gconv.Map(value[0])
  42. }
  43. return map[string]interface{}{}
  44. }
  45. // buildInFuncMaps implements build-in template function: maps
  46. func (view *View) buildInFuncMaps(value ...interface{}) []map[string]interface{} {
  47. if len(value) > 0 {
  48. return gconv.Maps(value[0])
  49. }
  50. return []map[string]interface{}{}
  51. }
  52. // buildInFuncEq implements build-in template function: eq
  53. func (view *View) buildInFuncEq(value interface{}, others ...interface{}) bool {
  54. s := gconv.String(value)
  55. for _, v := range others {
  56. if strings.Compare(s, gconv.String(v)) == 0 {
  57. return true
  58. }
  59. }
  60. return false
  61. }
  62. // buildInFuncNe implements build-in template function: ne
  63. func (view *View) buildInFuncNe(value, other interface{}) bool {
  64. return strings.Compare(gconv.String(value), gconv.String(other)) != 0
  65. }
  66. // buildInFuncLt implements build-in template function: lt
  67. func (view *View) buildInFuncLt(value, other interface{}) bool {
  68. s1 := gconv.String(value)
  69. s2 := gconv.String(other)
  70. if gstr.IsNumeric(s1) && gstr.IsNumeric(s2) {
  71. return gconv.Int64(value) < gconv.Int64(other)
  72. }
  73. return strings.Compare(s1, s2) < 0
  74. }
  75. // buildInFuncLe implements build-in template function: le
  76. func (view *View) buildInFuncLe(value, other interface{}) bool {
  77. s1 := gconv.String(value)
  78. s2 := gconv.String(other)
  79. if gstr.IsNumeric(s1) && gstr.IsNumeric(s2) {
  80. return gconv.Int64(value) <= gconv.Int64(other)
  81. }
  82. return strings.Compare(s1, s2) <= 0
  83. }
  84. // buildInFuncGt implements build-in template function: gt
  85. func (view *View) buildInFuncGt(value, other interface{}) bool {
  86. s1 := gconv.String(value)
  87. s2 := gconv.String(other)
  88. if gstr.IsNumeric(s1) && gstr.IsNumeric(s2) {
  89. return gconv.Int64(value) > gconv.Int64(other)
  90. }
  91. return strings.Compare(s1, s2) > 0
  92. }
  93. // buildInFuncGe implements build-in template function: ge
  94. func (view *View) buildInFuncGe(value, other interface{}) bool {
  95. s1 := gconv.String(value)
  96. s2 := gconv.String(other)
  97. if gstr.IsNumeric(s1) && gstr.IsNumeric(s2) {
  98. return gconv.Int64(value) >= gconv.Int64(other)
  99. }
  100. return strings.Compare(s1, s2) >= 0
  101. }
  102. // buildInFuncInclude implements build-in template function: include
  103. // Note that configuration AutoEncode does not affect the output of this function.
  104. func (view *View) buildInFuncInclude(file interface{}, data ...map[string]interface{}) htmltpl.HTML {
  105. var m map[string]interface{} = nil
  106. if len(data) > 0 {
  107. m = data[0]
  108. }
  109. path := gconv.String(file)
  110. if path == "" {
  111. return ""
  112. }
  113. // It will search the file internally.
  114. content, err := view.Parse(context.TODO(), path, m)
  115. if err != nil {
  116. return htmltpl.HTML(err.Error())
  117. }
  118. return htmltpl.HTML(content)
  119. }
  120. // buildInFuncText implements build-in template function: text
  121. func (view *View) buildInFuncText(html interface{}) string {
  122. return ghtml.StripTags(gconv.String(html))
  123. }
  124. // buildInFuncHtmlEncode implements build-in template function: html
  125. func (view *View) buildInFuncHtmlEncode(html interface{}) string {
  126. return ghtml.Entities(gconv.String(html))
  127. }
  128. // buildInFuncHtmlDecode implements build-in template function: htmldecode
  129. func (view *View) buildInFuncHtmlDecode(html interface{}) string {
  130. return ghtml.EntitiesDecode(gconv.String(html))
  131. }
  132. // buildInFuncUrlEncode implements build-in template function: url
  133. func (view *View) buildInFuncUrlEncode(url interface{}) string {
  134. return gurl.Encode(gconv.String(url))
  135. }
  136. // buildInFuncUrlDecode implements build-in template function: urldecode
  137. func (view *View) buildInFuncUrlDecode(url interface{}) string {
  138. if content, err := gurl.Decode(gconv.String(url)); err == nil {
  139. return content
  140. } else {
  141. return err.Error()
  142. }
  143. }
  144. // buildInFuncDate implements build-in template function: date
  145. func (view *View) buildInFuncDate(format interface{}, timestamp ...interface{}) string {
  146. t := int64(0)
  147. if len(timestamp) > 0 {
  148. t = gconv.Int64(timestamp[0])
  149. }
  150. if t == 0 {
  151. t = gtime.Timestamp()
  152. }
  153. return gtime.NewFromTimeStamp(t).Format(gconv.String(format))
  154. }
  155. // buildInFuncCompare implements build-in template function: compare
  156. func (view *View) buildInFuncCompare(value1, value2 interface{}) int {
  157. return strings.Compare(gconv.String(value1), gconv.String(value2))
  158. }
  159. // buildInFuncSubStr implements build-in template function: substr
  160. func (view *View) buildInFuncSubStr(start, end, str interface{}) string {
  161. return gstr.SubStrRune(gconv.String(str), gconv.Int(start), gconv.Int(end))
  162. }
  163. // buildInFuncStrLimit implements build-in template function: strlimit
  164. func (view *View) buildInFuncStrLimit(length, suffix, str interface{}) string {
  165. return gstr.StrLimitRune(gconv.String(str), gconv.Int(length), gconv.String(suffix))
  166. }
  167. // buildInFuncConcat implements build-in template function: concat
  168. func (view *View) buildInFuncConcat(str ...interface{}) string {
  169. var s string
  170. for _, v := range str {
  171. s += gconv.String(v)
  172. }
  173. return s
  174. }
  175. // buildInFuncReplace implements build-in template function: replace
  176. func (view *View) buildInFuncReplace(search, replace, str interface{}) string {
  177. return gstr.Replace(gconv.String(str), gconv.String(search), gconv.String(replace), -1)
  178. }
  179. // buildInFuncHighlight implements build-in template function: highlight
  180. func (view *View) buildInFuncHighlight(key, color, str interface{}) string {
  181. return gstr.Replace(gconv.String(str), gconv.String(key), fmt.Sprintf(`<span style="color:%v;">%v</span>`, color, key))
  182. }
  183. // buildInFuncHideStr implements build-in template function: hidestr
  184. func (view *View) buildInFuncHideStr(percent, hide, str interface{}) string {
  185. return gstr.HideStr(gconv.String(str), gconv.Int(percent), gconv.String(hide))
  186. }
  187. // buildInFuncToUpper implements build-in template function: toupper
  188. func (view *View) buildInFuncToUpper(str interface{}) string {
  189. return gstr.ToUpper(gconv.String(str))
  190. }
  191. // buildInFuncToLower implements build-in template function: toupper
  192. func (view *View) buildInFuncToLower(str interface{}) string {
  193. return gstr.ToLower(gconv.String(str))
  194. }
  195. // buildInFuncNl2Br implements build-in template function: nl2br
  196. func (view *View) buildInFuncNl2Br(str interface{}) string {
  197. return gstr.Nl2Br(gconv.String(str))
  198. }
  199. // buildInFuncJson implements build-in template function: json ,
  200. // which encodes and returns `value` as JSON string.
  201. func (view *View) buildInFuncJson(value interface{}) (string, error) {
  202. b, err := gjson.Marshal(value)
  203. return string(b), err
  204. }
  205. // buildInFuncXml implements build-in template function: xml ,
  206. // which encodes and returns `value` as XML string.
  207. func (view *View) buildInFuncXml(value interface{}, rootTag ...string) (string, error) {
  208. b, err := gjson.New(value).ToXml(rootTag...)
  209. return string(b), err
  210. }
  211. // buildInFuncXml implements build-in template function: ini ,
  212. // which encodes and returns `value` as XML string.
  213. func (view *View) buildInFuncIni(value interface{}) (string, error) {
  214. b, err := gjson.New(value).ToIni()
  215. return string(b), err
  216. }
  217. // buildInFuncYaml implements build-in template function: yaml ,
  218. // which encodes and returns `value` as YAML string.
  219. func (view *View) buildInFuncYaml(value interface{}) (string, error) {
  220. b, err := gjson.New(value).ToYaml()
  221. return string(b), err
  222. }
  223. // buildInFuncYamlIndent implements build-in template function: yamli ,
  224. // which encodes and returns `value` as YAML string with custom indent string.
  225. func (view *View) buildInFuncYamlIndent(value, indent interface{}) (string, error) {
  226. b, err := gjson.New(value).ToYamlIndent(gconv.String(indent))
  227. return string(b), err
  228. }
  229. // buildInFuncToml implements build-in template function: toml ,
  230. // which encodes and returns `value` as TOML string.
  231. func (view *View) buildInFuncToml(value interface{}) (string, error) {
  232. b, err := gjson.New(value).ToToml()
  233. return string(b), err
  234. }
  235. // buildInFuncPlus implements build-in template function: plus ,
  236. // which returns the result that pluses all `deltas` to `value`.
  237. func (view *View) buildInFuncPlus(value interface{}, deltas ...interface{}) string {
  238. result := gconv.Float64(value)
  239. for _, v := range deltas {
  240. result += gconv.Float64(v)
  241. }
  242. return gconv.String(result)
  243. }
  244. // buildInFuncMinus implements build-in template function: minus ,
  245. // which returns the result that subtracts all `deltas` from `value`.
  246. func (view *View) buildInFuncMinus(value interface{}, deltas ...interface{}) string {
  247. result := gconv.Float64(value)
  248. for _, v := range deltas {
  249. result -= gconv.Float64(v)
  250. }
  251. return gconv.String(result)
  252. }
  253. // buildInFuncTimes implements build-in template function: times ,
  254. // which returns the result that multiplies `value` by all of `values`.
  255. func (view *View) buildInFuncTimes(value interface{}, values ...interface{}) string {
  256. result := gconv.Float64(value)
  257. for _, v := range values {
  258. result *= gconv.Float64(v)
  259. }
  260. return gconv.String(result)
  261. }
  262. // buildInFuncDivide implements build-in template function: divide ,
  263. // which returns the result that divides `value` by all of `values`.
  264. func (view *View) buildInFuncDivide(value interface{}, values ...interface{}) string {
  265. result := gconv.Float64(value)
  266. for _, v := range values {
  267. value2Float64 := gconv.Float64(v)
  268. if value2Float64 == 0 {
  269. // Invalid `value2`.
  270. return "0"
  271. }
  272. result /= value2Float64
  273. }
  274. return gconv.String(result)
  275. }