github.com/wangyougui/gf/v2@v2.6.5/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/wangyougui/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/wangyougui/gf/v2"
    17  	"github.com/wangyougui/gf/v2/container/garray"
    18  	"github.com/wangyougui/gf/v2/container/gmap"
    19  	"github.com/wangyougui/gf/v2/internal/intlog"
    20  	"github.com/wangyougui/gf/v2/os/gcmd"
    21  	"github.com/wangyougui/gf/v2/os/gfile"
    22  	"github.com/wangyougui/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  }