github.com/gogf/gf/v2@v2.7.4/os/gview/gview.go (about) 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 7 // Package gview implements a template engine based on text/template. 8 // 9 // Reserved template variable names: 10 // I18nLanguage: Assign this variable to define i18n language for each page. 11 package gview 12 13 import ( 14 "context" 15 16 "github.com/gogf/gf/v2" 17 "github.com/gogf/gf/v2/container/garray" 18 "github.com/gogf/gf/v2/container/gmap" 19 "github.com/gogf/gf/v2/internal/intlog" 20 "github.com/gogf/gf/v2/os/gcmd" 21 "github.com/gogf/gf/v2/os/gfile" 22 "github.com/gogf/gf/v2/os/glog" 23 ) 24 25 // View object for template engine. 26 type View struct { 27 searchPaths *garray.StrArray // Searching array for path, NOT concurrent-safe for performance purpose. 28 data map[string]interface{} // Global template variables. 29 funcMap map[string]interface{} // Global template function map. 30 fileCacheMap *gmap.StrAnyMap // File cache map. 31 config Config // Extra configuration for the view. 32 } 33 34 type ( 35 Params = map[string]interface{} // Params is type for template params. 36 FuncMap = map[string]interface{} // FuncMap is type for custom template functions. 37 ) 38 39 const ( 40 commandEnvKeyForPath = "gf.gview.path" 41 ) 42 43 var ( 44 // Default view object. 45 defaultViewObj *View 46 ) 47 48 // checkAndInitDefaultView checks and initializes the default view object. 49 // The default view object will be initialized just once. 50 func checkAndInitDefaultView() { 51 if defaultViewObj == nil { 52 defaultViewObj = New() 53 } 54 } 55 56 // ParseContent parses the template content directly using the default view object 57 // and returns the parsed content. 58 func ParseContent(ctx context.Context, content string, params ...Params) (string, error) { 59 checkAndInitDefaultView() 60 return defaultViewObj.ParseContent(ctx, content, params...) 61 } 62 63 // New returns a new view object. 64 // The parameter `path` specifies the template directory path to load template files. 65 func New(path ...string) *View { 66 var ( 67 ctx = context.TODO() 68 ) 69 view := &View{ 70 searchPaths: garray.NewStrArray(), 71 data: make(map[string]interface{}), 72 funcMap: make(map[string]interface{}), 73 fileCacheMap: gmap.NewStrAnyMap(true), 74 config: DefaultConfig(), 75 } 76 if len(path) > 0 && len(path[0]) > 0 { 77 if err := view.SetPath(path[0]); err != nil { 78 intlog.Errorf(context.TODO(), `%+v`, err) 79 } 80 } else { 81 // Customized dir path from env/cmd. 82 if envPath := gcmd.GetOptWithEnv(commandEnvKeyForPath).String(); envPath != "" { 83 if gfile.Exists(envPath) { 84 if err := view.SetPath(envPath); err != nil { 85 intlog.Errorf(context.TODO(), `%+v`, err) 86 } 87 } else { 88 if errorPrint() { 89 glog.Errorf(ctx, "Template directory path does not exist: %s", envPath) 90 } 91 } 92 } else { 93 // Dir path of working dir. 94 if pwdPath := gfile.Pwd(); pwdPath != "" { 95 if err := view.SetPath(pwdPath); err != nil { 96 intlog.Errorf(context.TODO(), `%+v`, err) 97 } 98 } 99 // Dir path of binary. 100 if selfPath := gfile.SelfDir(); selfPath != "" && gfile.Exists(selfPath) { 101 if err := view.AddPath(selfPath); err != nil { 102 intlog.Errorf(context.TODO(), `%+v`, err) 103 } 104 } 105 // Dir path of main package. 106 if mainPath := gfile.MainPkgPath(); mainPath != "" && gfile.Exists(mainPath) { 107 if err := view.AddPath(mainPath); err != nil { 108 intlog.Errorf(context.TODO(), `%+v`, err) 109 } 110 } 111 } 112 } 113 view.SetDelimiters("{{", "}}") 114 // default build-in variables. 115 view.data["GF"] = map[string]interface{}{ 116 "version": gf.VERSION, 117 } 118 // default build-in functions. 119 view.BindFuncMap(FuncMap{ 120 "eq": view.buildInFuncEq, 121 "ne": view.buildInFuncNe, 122 "lt": view.buildInFuncLt, 123 "le": view.buildInFuncLe, 124 "gt": view.buildInFuncGt, 125 "ge": view.buildInFuncGe, 126 "text": view.buildInFuncText, 127 "html": view.buildInFuncHtmlEncode, 128 "htmlencode": view.buildInFuncHtmlEncode, 129 "htmldecode": view.buildInFuncHtmlDecode, 130 "encode": view.buildInFuncHtmlEncode, 131 "decode": view.buildInFuncHtmlDecode, 132 "url": view.buildInFuncUrlEncode, 133 "urlencode": view.buildInFuncUrlEncode, 134 "urldecode": view.buildInFuncUrlDecode, 135 "date": view.buildInFuncDate, 136 "substr": view.buildInFuncSubStr, 137 "strlimit": view.buildInFuncStrLimit, 138 "concat": view.buildInFuncConcat, 139 "replace": view.buildInFuncReplace, 140 "compare": view.buildInFuncCompare, 141 "hidestr": view.buildInFuncHideStr, 142 "highlight": view.buildInFuncHighlight, 143 "toupper": view.buildInFuncToUpper, 144 "tolower": view.buildInFuncToLower, 145 "nl2br": view.buildInFuncNl2Br, 146 "include": view.buildInFuncInclude, 147 "dump": view.buildInFuncDump, 148 "map": view.buildInFuncMap, 149 "maps": view.buildInFuncMaps, 150 "json": view.buildInFuncJson, 151 "xml": view.buildInFuncXml, 152 "ini": view.buildInFuncIni, 153 "yaml": view.buildInFuncYaml, 154 "yamli": view.buildInFuncYamlIndent, 155 "toml": view.buildInFuncToml, 156 "plus": view.buildInFuncPlus, 157 "minus": view.buildInFuncMinus, 158 "times": view.buildInFuncTimes, 159 "divide": view.buildInFuncDivide, 160 }) 161 return view 162 }