gf/os/gview/gview.go

157 lines
4.9 KiB
Go
Raw Normal View History

2021-01-17 21:46:25 +08:00
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
2017-12-29 16:03:30 +08:00
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
2017-12-29 16:03:30 +08:00
2019-01-15 23:27:47 +08:00
// Package gview implements a template engine based on text/template.
//
// Reserved template variable names:
// I18nLanguage: Assign this variable to define i18n language for each page.
package gview
import (
"context"
2021-10-11 21:41:56 +08:00
"github.com/gogf/gf/v2/container/gmap"
"github.com/gogf/gf/v2/internal/intlog"
2021-10-11 21:41:56 +08:00
"github.com/gogf/gf/v2"
"github.com/gogf/gf/v2/container/garray"
"github.com/gogf/gf/v2/os/gcmd"
"github.com/gogf/gf/v2/os/gfile"
"github.com/gogf/gf/v2/os/glog"
)
2019-06-15 22:06:47 +08:00
// View object for template engine.
type View struct {
paths *garray.StrArray // Searching array for path, NOT concurrent-safe for performance purpose.
2019-10-31 23:37:33 +08:00
data map[string]interface{} // Global template variables.
funcMap map[string]interface{} // Global template function map.
fileCacheMap *gmap.StrAnyMap // File cache map.
2019-12-26 11:03:59 +08:00
config Config // Extra configuration for the view.
}
type (
Params = map[string]interface{} // Params is type for template params.
FuncMap = map[string]interface{} // FuncMap is type for custom template functions.
)
const (
commandEnvKeyForPath = "gf.gview.path"
)
var (
// Default view object.
defaultViewObj *View
)
2018-09-26 09:58:49 +08:00
// checkAndInitDefaultView checks and initializes the default view object.
// The default view object will be initialized just once.
2018-09-26 09:58:49 +08:00
func checkAndInitDefaultView() {
2019-06-19 09:06:52 +08:00
if defaultViewObj == nil {
defaultViewObj = New()
}
2018-09-26 09:58:49 +08:00
}
// ParseContent parses the template content directly using the default view object
// and returns the parsed content.
func ParseContent(ctx context.Context, content string, params ...Params) (string, error) {
2019-06-19 09:06:52 +08:00
checkAndInitDefaultView()
return defaultViewObj.ParseContent(ctx, content, params...)
}
// New returns a new view object.
// The parameter `path` specifies the template directory path to load template files.
2019-06-19 09:06:52 +08:00
func New(path ...string) *View {
2021-09-27 21:27:24 +08:00
var (
ctx = context.TODO()
)
2019-06-19 09:06:52 +08:00
view := &View{
2019-10-31 23:37:33 +08:00
paths: garray.NewStrArray(),
data: make(map[string]interface{}),
funcMap: make(map[string]interface{}),
fileCacheMap: gmap.NewStrAnyMap(true),
config: DefaultConfig(),
2019-06-19 09:06:52 +08:00
}
if len(path) > 0 && len(path[0]) > 0 {
2019-11-01 15:31:26 +08:00
if err := view.SetPath(path[0]); err != nil {
intlog.Error(context.TODO(), err)
2019-11-01 15:31:26 +08:00
}
2019-06-19 09:06:52 +08:00
} else {
// Customized dir path from env/cmd.
if envPath := gcmd.GetOptWithEnv(commandEnvKeyForPath).String(); envPath != "" {
2019-06-19 09:06:52 +08:00
if gfile.Exists(envPath) {
2019-11-01 15:31:26 +08:00
if err := view.SetPath(envPath); err != nil {
intlog.Error(context.TODO(), err)
2019-11-01 15:31:26 +08:00
}
2019-06-19 09:06:52 +08:00
} else {
if errorPrint() {
2021-09-27 21:27:24 +08:00
glog.Errorf(ctx, "Template directory path does not exist: %s", envPath)
2019-06-19 09:06:52 +08:00
}
}
} else {
// Dir path of working dir.
2019-11-01 15:31:26 +08:00
if err := view.SetPath(gfile.Pwd()); err != nil {
intlog.Error(context.TODO(), err)
2019-11-01 15:31:26 +08:00
}
2019-06-19 09:06:52 +08:00
// Dir path of binary.
if selfPath := gfile.SelfDir(); selfPath != "" && gfile.Exists(selfPath) {
2019-11-01 15:31:26 +08:00
if err := view.AddPath(selfPath); err != nil {
intlog.Error(context.TODO(), err)
2019-11-01 15:31:26 +08:00
}
2019-06-19 09:06:52 +08:00
}
// Dir path of main package.
if mainPath := gfile.MainPkgPath(); mainPath != "" && gfile.Exists(mainPath) {
2019-11-01 15:31:26 +08:00
if err := view.AddPath(mainPath); err != nil {
intlog.Error(context.TODO(), err)
2019-11-01 15:31:26 +08:00
}
2019-06-19 09:06:52 +08:00
}
}
}
view.SetDelimiters("{{", "}}")
// default build-in variables.
view.data["GF"] = map[string]interface{}{
"version": gf.VERSION,
}
// default build-in functions.
view.BindFuncMap(FuncMap{
"eq": view.buildInFuncEq,
"ne": view.buildInFuncNe,
"lt": view.buildInFuncLt,
"le": view.buildInFuncLe,
"gt": view.buildInFuncGt,
"ge": view.buildInFuncGe,
"text": view.buildInFuncText,
"html": view.buildInFuncHtmlEncode,
"htmlencode": view.buildInFuncHtmlEncode,
"htmldecode": view.buildInFuncHtmlDecode,
"encode": view.buildInFuncHtmlEncode,
"decode": view.buildInFuncHtmlDecode,
"url": view.buildInFuncUrlEncode,
"urlencode": view.buildInFuncUrlEncode,
"urldecode": view.buildInFuncUrlDecode,
"date": view.buildInFuncDate,
"substr": view.buildInFuncSubStr,
"strlimit": view.buildInFuncStrLimit,
"concat": view.buildInFuncConcat,
"replace": view.buildInFuncReplace,
"compare": view.buildInFuncCompare,
"hidestr": view.buildInFuncHideStr,
"highlight": view.buildInFuncHighlight,
"toupper": view.buildInFuncToUpper,
"tolower": view.buildInFuncToLower,
"nl2br": view.buildInFuncNl2Br,
"include": view.buildInFuncInclude,
"dump": view.buildInFuncDump,
"map": view.buildInFuncMap,
"maps": view.buildInFuncMaps,
"json": view.buildInFuncJson,
"plus": view.buildInFuncPlus,
"minus": view.buildInFuncMinus,
"times": view.buildInFuncTimes,
"divide": view.buildInFuncDivide,
})
2019-12-26 11:03:59 +08:00
2019-06-19 09:06:52 +08:00
return view
}