github.com/gogf/gf@v1.16.9/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 "github.com/gogf/gf/container/gmap" 16 "github.com/gogf/gf/internal/intlog" 17 18 "github.com/gogf/gf" 19 "github.com/gogf/gf/container/garray" 20 "github.com/gogf/gf/os/gcmd" 21 "github.com/gogf/gf/os/gfile" 22 "github.com/gogf/gf/os/glog" 23 ) 24 25 // View object for template engine. 26 type View struct { 27 paths *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 view := &View{ 67 paths: garray.NewStrArray(), 68 data: make(map[string]interface{}), 69 funcMap: make(map[string]interface{}), 70 fileCacheMap: gmap.NewStrAnyMap(true), 71 config: DefaultConfig(), 72 } 73 if len(path) > 0 && len(path[0]) > 0 { 74 if err := view.SetPath(path[0]); err != nil { 75 intlog.Error(context.TODO(), err) 76 } 77 } else { 78 // Customized dir path from env/cmd. 79 if envPath := gcmd.GetOptWithEnv(commandEnvKeyForPath).String(); envPath != "" { 80 if gfile.Exists(envPath) { 81 if err := view.SetPath(envPath); err != nil { 82 intlog.Error(context.TODO(), err) 83 } 84 } else { 85 if errorPrint() { 86 glog.Errorf("Template directory path does not exist: %s", envPath) 87 } 88 } 89 } else { 90 // Dir path of working dir. 91 if err := view.SetPath(gfile.Pwd()); err != nil { 92 intlog.Error(context.TODO(), err) 93 } 94 // Dir path of binary. 95 if selfPath := gfile.SelfDir(); selfPath != "" && gfile.Exists(selfPath) { 96 if err := view.AddPath(selfPath); err != nil { 97 intlog.Error(context.TODO(), err) 98 } 99 } 100 // Dir path of main package. 101 if mainPath := gfile.MainPkgPath(); mainPath != "" && gfile.Exists(mainPath) { 102 if err := view.AddPath(mainPath); err != nil { 103 intlog.Error(context.TODO(), err) 104 } 105 } 106 } 107 } 108 view.SetDelimiters("{{", "}}") 109 // default build-in variables. 110 view.data["GF"] = map[string]interface{}{ 111 "version": gf.VERSION, 112 } 113 // default build-in functions. 114 view.BindFuncMap(FuncMap{ 115 "eq": view.buildInFuncEq, 116 "ne": view.buildInFuncNe, 117 "lt": view.buildInFuncLt, 118 "le": view.buildInFuncLe, 119 "gt": view.buildInFuncGt, 120 "ge": view.buildInFuncGe, 121 "text": view.buildInFuncText, 122 "html": view.buildInFuncHtmlEncode, 123 "htmlencode": view.buildInFuncHtmlEncode, 124 "htmldecode": view.buildInFuncHtmlDecode, 125 "encode": view.buildInFuncHtmlEncode, 126 "decode": view.buildInFuncHtmlDecode, 127 "url": view.buildInFuncUrlEncode, 128 "urlencode": view.buildInFuncUrlEncode, 129 "urldecode": view.buildInFuncUrlDecode, 130 "date": view.buildInFuncDate, 131 "substr": view.buildInFuncSubStr, 132 "strlimit": view.buildInFuncStrLimit, 133 "concat": view.buildInFuncConcat, 134 "replace": view.buildInFuncReplace, 135 "compare": view.buildInFuncCompare, 136 "hidestr": view.buildInFuncHideStr, 137 "highlight": view.buildInFuncHighlight, 138 "toupper": view.buildInFuncToUpper, 139 "tolower": view.buildInFuncToLower, 140 "nl2br": view.buildInFuncNl2Br, 141 "include": view.buildInFuncInclude, 142 "dump": view.buildInFuncDump, 143 "map": view.buildInFuncMap, 144 "maps": view.buildInFuncMaps, 145 "json": view.buildInFuncJson, 146 "plus": view.buildInFuncPlus, 147 "minus": view.buildInFuncMinus, 148 "times": view.buildInFuncTimes, 149 "divide": view.buildInFuncDivide, 150 }) 151 152 return view 153 }