default.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. // Copyright 2016 José Santos <henrique_1609@me.com>
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package jet
  15. import (
  16. "encoding/json"
  17. "fmt"
  18. "html"
  19. "io"
  20. "net/url"
  21. "reflect"
  22. "strings"
  23. "text/template"
  24. )
  25. var defaultExtensions = []string{
  26. ".html.jet",
  27. ".jet.html",
  28. ".jet",
  29. }
  30. var defaultVariables map[string]reflect.Value
  31. func init() {
  32. defaultVariables = map[string]reflect.Value{
  33. "lower": reflect.ValueOf(strings.ToLower),
  34. "upper": reflect.ValueOf(strings.ToUpper),
  35. "hasPrefix": reflect.ValueOf(strings.HasPrefix),
  36. "hasSuffix": reflect.ValueOf(strings.HasSuffix),
  37. "repeat": reflect.ValueOf(strings.Repeat),
  38. "replace": reflect.ValueOf(strings.Replace),
  39. "split": reflect.ValueOf(strings.Split),
  40. "trimSpace": reflect.ValueOf(strings.TrimSpace),
  41. "map": reflect.ValueOf(newMap),
  42. "html": reflect.ValueOf(html.EscapeString),
  43. "url": reflect.ValueOf(url.QueryEscape),
  44. "safeHtml": reflect.ValueOf(SafeWriter(template.HTMLEscape)),
  45. "safeJs": reflect.ValueOf(SafeWriter(template.JSEscape)),
  46. "raw": reflect.ValueOf(SafeWriter(unsafePrinter)),
  47. "unsafe": reflect.ValueOf(SafeWriter(unsafePrinter)),
  48. "writeJson": reflect.ValueOf(jsonRenderer),
  49. "json": reflect.ValueOf(json.Marshal),
  50. "isset": reflect.ValueOf(Func(func(a Arguments) reflect.Value {
  51. a.RequireNumOfArguments("isset", 1, -1)
  52. for i := 0; i < len(a.argExpr); i++ {
  53. if !a.runtime.isSet(a.argExpr[i]) {
  54. return valueBoolFALSE
  55. }
  56. }
  57. return valueBoolTRUE
  58. })),
  59. "len": reflect.ValueOf(Func(func(a Arguments) reflect.Value {
  60. a.RequireNumOfArguments("len", 1, 1)
  61. expression := a.Get(0)
  62. if expression.Kind() == reflect.Ptr {
  63. expression = expression.Elem()
  64. }
  65. switch expression.Kind() {
  66. case reflect.Array, reflect.Chan, reflect.Slice, reflect.Map, reflect.String:
  67. return reflect.ValueOf(expression.Len())
  68. case reflect.Struct:
  69. return reflect.ValueOf(expression.NumField())
  70. }
  71. a.Panicf("inválid value type %s in len builtin", expression.Type())
  72. return reflect.Value{}
  73. })),
  74. "includeIfExists": reflect.ValueOf(Func(func(a Arguments) reflect.Value {
  75. a.RequireNumOfArguments("includeIfExists", 1, 2)
  76. t, err := a.runtime.set.GetTemplate(a.Get(0).String())
  77. // If template exists but returns an error then panic instead of failing silently
  78. if t != nil && err != nil {
  79. panic(err)
  80. }
  81. if err != nil {
  82. return hiddenFALSE
  83. }
  84. a.runtime.newScope()
  85. a.runtime.blocks = t.processedBlocks
  86. Root := t.Root
  87. if t.extends != nil {
  88. Root = t.extends.Root
  89. }
  90. if a.NumOfArguments() > 1 {
  91. c := a.runtime.context
  92. a.runtime.context = a.Get(1)
  93. a.runtime.executeList(Root)
  94. a.runtime.context = c
  95. } else {
  96. a.runtime.executeList(Root)
  97. }
  98. a.runtime.releaseScope()
  99. return hiddenTRUE
  100. })),
  101. }
  102. }
  103. type hiddenBool bool
  104. func (m hiddenBool) Render(r *Runtime) {
  105. }
  106. var hiddenTRUE = reflect.ValueOf(hiddenBool(true))
  107. var hiddenFALSE = reflect.ValueOf(hiddenBool(false))
  108. func jsonRenderer(v interface{}) RendererFunc {
  109. return func(r *Runtime) {
  110. err := json.NewEncoder(r.Writer).Encode(v)
  111. if err != nil {
  112. panic(err)
  113. }
  114. }
  115. }
  116. func unsafePrinter(w io.Writer, b []byte) {
  117. w.Write(b)
  118. }
  119. // SafeWriter escapee func. Functions implementing this type will write directly into the writer,
  120. // skipping the escape phase; use this type to create special types of escapee funcs.
  121. type SafeWriter func(io.Writer, []byte)
  122. func newMap(values ...interface{}) (nmap map[string]interface{}) {
  123. if len(values)%2 > 0 {
  124. panic("new map: invalid number of arguments on call to map")
  125. }
  126. nmap = make(map[string]interface{})
  127. for i := 0; i < len(values); i += 2 {
  128. nmap[fmt.Sprint(values[i])] = values[i+1]
  129. }
  130. return
  131. }