2021-01-04 00:05:02 +08:00
|
|
|
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
|
2019-04-22 15:47:59 +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.
|
|
|
|
|
|
|
|
package gview
|
|
|
|
|
|
|
|
import (
|
2021-11-18 15:20:37 +08:00
|
|
|
"bytes"
|
2021-05-13 00:16:45 +08:00
|
|
|
"context"
|
2019-04-22 15:47:59 +08:00
|
|
|
"fmt"
|
2021-11-15 20:49:02 +08:00
|
|
|
htmltpl "html/template"
|
2019-04-22 15:47:59 +08:00
|
|
|
"strings"
|
2019-07-29 21:01:19 +08:00
|
|
|
|
2021-10-11 21:41:56 +08:00
|
|
|
"github.com/gogf/gf/v2/encoding/ghtml"
|
2022-01-17 15:55:45 +08:00
|
|
|
"github.com/gogf/gf/v2/encoding/gjson"
|
2021-10-11 21:41:56 +08:00
|
|
|
"github.com/gogf/gf/v2/encoding/gurl"
|
|
|
|
"github.com/gogf/gf/v2/os/gtime"
|
|
|
|
"github.com/gogf/gf/v2/text/gstr"
|
|
|
|
"github.com/gogf/gf/v2/util/gconv"
|
2022-04-13 21:08:12 +08:00
|
|
|
"github.com/gogf/gf/v2/util/gmode"
|
2021-11-15 20:49:02 +08:00
|
|
|
"github.com/gogf/gf/v2/util/gutil"
|
2019-04-22 15:47:59 +08:00
|
|
|
)
|
|
|
|
|
2020-11-08 17:11:04 +08:00
|
|
|
// buildInFuncDump implements build-in template function: dump
|
2021-11-18 20:07:24 +08:00
|
|
|
func (view *View) buildInFuncDump(values ...interface{}) string {
|
2021-11-18 15:20:37 +08:00
|
|
|
buffer := bytes.NewBuffer(nil)
|
2021-12-17 17:42:18 +08:00
|
|
|
buffer.WriteString("\n")
|
2021-11-18 15:20:37 +08:00
|
|
|
buffer.WriteString("<!--\n")
|
2022-04-13 21:08:12 +08:00
|
|
|
if gmode.IsDevelop() {
|
|
|
|
for _, v := range values {
|
|
|
|
gutil.DumpTo(buffer, v, gutil.DumpOption{})
|
|
|
|
buffer.WriteString("\n")
|
|
|
|
}
|
|
|
|
} else {
|
2022-04-13 21:58:35 +08:00
|
|
|
buffer.WriteString("dump feature is disabled as process is not running in develop mode\n")
|
2019-12-08 22:55:32 +08:00
|
|
|
}
|
2021-11-18 15:20:37 +08:00
|
|
|
buffer.WriteString("-->\n")
|
2021-11-18 20:07:24 +08:00
|
|
|
return buffer.String()
|
2019-12-08 22:55:32 +08:00
|
|
|
}
|
|
|
|
|
2020-11-08 17:11:04 +08:00
|
|
|
// buildInFuncMap implements build-in template function: map
|
|
|
|
func (view *View) buildInFuncMap(value ...interface{}) map[string]interface{} {
|
|
|
|
if len(value) > 0 {
|
|
|
|
return gconv.Map(value[0])
|
|
|
|
}
|
|
|
|
return map[string]interface{}{}
|
|
|
|
}
|
|
|
|
|
|
|
|
// buildInFuncMaps implements build-in template function: maps
|
|
|
|
func (view *View) buildInFuncMaps(value ...interface{}) []map[string]interface{} {
|
|
|
|
if len(value) > 0 {
|
|
|
|
return gconv.Maps(value[0])
|
|
|
|
}
|
|
|
|
return []map[string]interface{}{}
|
|
|
|
}
|
|
|
|
|
|
|
|
// buildInFuncEq implements build-in template function: eq
|
|
|
|
func (view *View) buildInFuncEq(value interface{}, others ...interface{}) bool {
|
2019-04-25 23:23:24 +08:00
|
|
|
s := gconv.String(value)
|
|
|
|
for _, v := range others {
|
2021-01-04 00:05:02 +08:00
|
|
|
if strings.Compare(s, gconv.String(v)) == 0 {
|
|
|
|
return true
|
2019-04-25 23:23:24 +08:00
|
|
|
}
|
|
|
|
}
|
2021-01-04 00:05:02 +08:00
|
|
|
return false
|
2019-04-25 23:23:24 +08:00
|
|
|
}
|
|
|
|
|
2020-11-08 17:11:04 +08:00
|
|
|
// buildInFuncNe implements build-in template function: ne
|
|
|
|
func (view *View) buildInFuncNe(value, other interface{}) bool {
|
2019-04-25 23:23:24 +08:00
|
|
|
return strings.Compare(gconv.String(value), gconv.String(other)) != 0
|
|
|
|
}
|
|
|
|
|
2020-11-08 17:11:04 +08:00
|
|
|
// buildInFuncLt implements build-in template function: lt
|
|
|
|
func (view *View) buildInFuncLt(value, other interface{}) bool {
|
2019-04-25 23:23:24 +08:00
|
|
|
s1 := gconv.String(value)
|
|
|
|
s2 := gconv.String(other)
|
|
|
|
if gstr.IsNumeric(s1) && gstr.IsNumeric(s2) {
|
|
|
|
return gconv.Int64(value) < gconv.Int64(other)
|
|
|
|
}
|
|
|
|
return strings.Compare(s1, s2) < 0
|
|
|
|
}
|
|
|
|
|
2020-11-08 17:11:04 +08:00
|
|
|
// buildInFuncLe implements build-in template function: le
|
|
|
|
func (view *View) buildInFuncLe(value, other interface{}) bool {
|
2019-04-25 23:23:24 +08:00
|
|
|
s1 := gconv.String(value)
|
|
|
|
s2 := gconv.String(other)
|
|
|
|
if gstr.IsNumeric(s1) && gstr.IsNumeric(s2) {
|
|
|
|
return gconv.Int64(value) <= gconv.Int64(other)
|
|
|
|
}
|
|
|
|
return strings.Compare(s1, s2) <= 0
|
|
|
|
}
|
|
|
|
|
2020-11-08 17:11:04 +08:00
|
|
|
// buildInFuncGt implements build-in template function: gt
|
|
|
|
func (view *View) buildInFuncGt(value, other interface{}) bool {
|
2019-04-25 23:23:24 +08:00
|
|
|
s1 := gconv.String(value)
|
|
|
|
s2 := gconv.String(other)
|
|
|
|
if gstr.IsNumeric(s1) && gstr.IsNumeric(s2) {
|
|
|
|
return gconv.Int64(value) > gconv.Int64(other)
|
|
|
|
}
|
|
|
|
return strings.Compare(s1, s2) > 0
|
|
|
|
}
|
|
|
|
|
2020-11-08 17:11:04 +08:00
|
|
|
// buildInFuncGe implements build-in template function: ge
|
|
|
|
func (view *View) buildInFuncGe(value, other interface{}) bool {
|
2019-04-25 23:23:24 +08:00
|
|
|
s1 := gconv.String(value)
|
|
|
|
s2 := gconv.String(other)
|
|
|
|
if gstr.IsNumeric(s1) && gstr.IsNumeric(s2) {
|
|
|
|
return gconv.Int64(value) >= gconv.Int64(other)
|
|
|
|
}
|
|
|
|
return strings.Compare(s1, s2) >= 0
|
|
|
|
}
|
|
|
|
|
2020-11-08 17:11:04 +08:00
|
|
|
// buildInFuncInclude implements build-in template function: include
|
2020-01-12 22:26:07 +08:00
|
|
|
// Note that configuration AutoEncode does not affect the output of this function.
|
2020-11-08 17:11:04 +08:00
|
|
|
func (view *View) buildInFuncInclude(file interface{}, data ...map[string]interface{}) htmltpl.HTML {
|
2019-06-19 09:06:52 +08:00
|
|
|
var m map[string]interface{} = nil
|
|
|
|
if len(data) > 0 {
|
|
|
|
m = data[0]
|
|
|
|
}
|
2019-10-17 20:31:03 +08:00
|
|
|
path := gconv.String(file)
|
|
|
|
if path == "" {
|
|
|
|
return ""
|
|
|
|
}
|
2019-08-16 00:29:14 +08:00
|
|
|
// It will search the file internally.
|
2021-05-13 00:16:45 +08:00
|
|
|
content, err := view.Parse(context.TODO(), path, m)
|
2019-06-19 09:06:52 +08:00
|
|
|
if err != nil {
|
2020-01-12 22:26:07 +08:00
|
|
|
return htmltpl.HTML(err.Error())
|
2019-06-19 09:06:52 +08:00
|
|
|
}
|
2020-01-12 22:26:07 +08:00
|
|
|
return htmltpl.HTML(content)
|
2019-04-22 15:47:59 +08:00
|
|
|
}
|
|
|
|
|
2020-11-08 17:11:04 +08:00
|
|
|
// buildInFuncText implements build-in template function: text
|
|
|
|
func (view *View) buildInFuncText(html interface{}) string {
|
2019-06-19 09:06:52 +08:00
|
|
|
return ghtml.StripTags(gconv.String(html))
|
2019-04-22 15:47:59 +08:00
|
|
|
}
|
|
|
|
|
2020-11-08 17:11:04 +08:00
|
|
|
// buildInFuncHtmlEncode implements build-in template function: html
|
|
|
|
func (view *View) buildInFuncHtmlEncode(html interface{}) string {
|
2019-06-19 09:06:52 +08:00
|
|
|
return ghtml.Entities(gconv.String(html))
|
2019-04-22 15:47:59 +08:00
|
|
|
}
|
|
|
|
|
2020-11-08 17:11:04 +08:00
|
|
|
// buildInFuncHtmlDecode implements build-in template function: htmldecode
|
|
|
|
func (view *View) buildInFuncHtmlDecode(html interface{}) string {
|
2019-06-19 09:06:52 +08:00
|
|
|
return ghtml.EntitiesDecode(gconv.String(html))
|
2019-04-22 15:47:59 +08:00
|
|
|
}
|
|
|
|
|
2020-11-08 17:11:04 +08:00
|
|
|
// buildInFuncUrlEncode implements build-in template function: url
|
|
|
|
func (view *View) buildInFuncUrlEncode(url interface{}) string {
|
2019-06-19 09:06:52 +08:00
|
|
|
return gurl.Encode(gconv.String(url))
|
2019-04-22 15:47:59 +08:00
|
|
|
}
|
|
|
|
|
2020-11-08 17:11:04 +08:00
|
|
|
// buildInFuncUrlDecode implements build-in template function: urldecode
|
|
|
|
func (view *View) buildInFuncUrlDecode(url interface{}) string {
|
2019-06-19 09:06:52 +08:00
|
|
|
if content, err := gurl.Decode(gconv.String(url)); err == nil {
|
|
|
|
return content
|
|
|
|
} else {
|
|
|
|
return err.Error()
|
|
|
|
}
|
2019-04-22 15:47:59 +08:00
|
|
|
}
|
|
|
|
|
2020-11-08 17:11:04 +08:00
|
|
|
// buildInFuncDate implements build-in template function: date
|
|
|
|
func (view *View) buildInFuncDate(format interface{}, timestamp ...interface{}) string {
|
2019-06-19 09:06:52 +08:00
|
|
|
t := int64(0)
|
|
|
|
if len(timestamp) > 0 {
|
|
|
|
t = gconv.Int64(timestamp[0])
|
|
|
|
}
|
|
|
|
if t == 0 {
|
2020-01-05 19:55:17 +08:00
|
|
|
t = gtime.Timestamp()
|
2019-06-19 09:06:52 +08:00
|
|
|
}
|
2019-11-07 20:56:17 +08:00
|
|
|
return gtime.NewFromTimeStamp(t).Format(gconv.String(format))
|
2019-04-22 15:47:59 +08:00
|
|
|
}
|
|
|
|
|
2020-11-08 17:11:04 +08:00
|
|
|
// buildInFuncCompare implements build-in template function: compare
|
|
|
|
func (view *View) buildInFuncCompare(value1, value2 interface{}) int {
|
2019-06-19 09:06:52 +08:00
|
|
|
return strings.Compare(gconv.String(value1), gconv.String(value2))
|
2019-04-22 15:47:59 +08:00
|
|
|
}
|
|
|
|
|
2020-11-08 17:11:04 +08:00
|
|
|
// buildInFuncSubStr implements build-in template function: substr
|
|
|
|
func (view *View) buildInFuncSubStr(start, end, str interface{}) string {
|
2020-04-07 23:53:17 +08:00
|
|
|
return gstr.SubStrRune(gconv.String(str), gconv.Int(start), gconv.Int(end))
|
2019-04-22 15:47:59 +08:00
|
|
|
}
|
|
|
|
|
2020-11-08 17:11:04 +08:00
|
|
|
// buildInFuncStrLimit implements build-in template function: strlimit
|
|
|
|
func (view *View) buildInFuncStrLimit(length, suffix, str interface{}) string {
|
2020-04-07 23:53:17 +08:00
|
|
|
return gstr.StrLimitRune(gconv.String(str), gconv.Int(length), gconv.String(suffix))
|
2019-04-22 15:47:59 +08:00
|
|
|
}
|
|
|
|
|
2020-11-08 17:11:04 +08:00
|
|
|
// buildInFuncConcat implements build-in template function: concat
|
|
|
|
func (view *View) buildInFuncConcat(str ...interface{}) string {
|
2020-01-05 19:55:17 +08:00
|
|
|
var s string
|
|
|
|
for _, v := range str {
|
|
|
|
s += gconv.String(v)
|
|
|
|
}
|
|
|
|
return s
|
|
|
|
}
|
|
|
|
|
2020-11-08 17:11:04 +08:00
|
|
|
// buildInFuncReplace implements build-in template function: replace
|
|
|
|
func (view *View) buildInFuncReplace(search, replace, str interface{}) string {
|
2019-11-07 20:56:17 +08:00
|
|
|
return gstr.Replace(gconv.String(str), gconv.String(search), gconv.String(replace), -1)
|
2019-04-22 15:47:59 +08:00
|
|
|
}
|
|
|
|
|
2020-11-08 17:11:04 +08:00
|
|
|
// buildInFuncHighlight implements build-in template function: highlight
|
|
|
|
func (view *View) buildInFuncHighlight(key, color, str interface{}) string {
|
2019-11-07 20:56:17 +08:00
|
|
|
return gstr.Replace(gconv.String(str), gconv.String(key), fmt.Sprintf(`<span style="color:%v;">%v</span>`, color, key))
|
2019-04-22 15:47:59 +08:00
|
|
|
}
|
|
|
|
|
2020-11-08 17:11:04 +08:00
|
|
|
// buildInFuncHideStr implements build-in template function: hidestr
|
|
|
|
func (view *View) buildInFuncHideStr(percent, hide, str interface{}) string {
|
2019-11-07 20:56:17 +08:00
|
|
|
return gstr.HideStr(gconv.String(str), gconv.Int(percent), gconv.String(hide))
|
|
|
|
}
|
|
|
|
|
2020-11-08 17:11:04 +08:00
|
|
|
// buildInFuncToUpper implements build-in template function: toupper
|
|
|
|
func (view *View) buildInFuncToUpper(str interface{}) string {
|
2019-06-19 09:06:52 +08:00
|
|
|
return gstr.ToUpper(gconv.String(str))
|
2019-04-22 15:47:59 +08:00
|
|
|
}
|
|
|
|
|
2020-11-08 17:11:04 +08:00
|
|
|
// buildInFuncToLower implements build-in template function: toupper
|
|
|
|
func (view *View) buildInFuncToLower(str interface{}) string {
|
2019-06-19 09:06:52 +08:00
|
|
|
return gstr.ToLower(gconv.String(str))
|
2019-04-22 15:47:59 +08:00
|
|
|
}
|
|
|
|
|
2020-11-08 17:11:04 +08:00
|
|
|
// buildInFuncNl2Br implements build-in template function: nl2br
|
|
|
|
func (view *View) buildInFuncNl2Br(str interface{}) string {
|
2019-06-19 09:06:52 +08:00
|
|
|
return gstr.Nl2Br(gconv.String(str))
|
2019-04-22 15:47:59 +08:00
|
|
|
}
|
2020-11-28 22:48:01 +08:00
|
|
|
|
|
|
|
// buildInFuncJson implements build-in template function: json ,
|
2021-08-25 20:00:53 +08:00
|
|
|
// which encodes and returns `value` as JSON string.
|
2020-11-28 22:48:01 +08:00
|
|
|
func (view *View) buildInFuncJson(value interface{}) (string, error) {
|
2022-01-17 15:55:45 +08:00
|
|
|
b, err := gjson.Marshal(value)
|
|
|
|
return string(b), err
|
|
|
|
}
|
|
|
|
|
|
|
|
// buildInFuncXml implements build-in template function: xml ,
|
|
|
|
// which encodes and returns `value` as XML string.
|
|
|
|
func (view *View) buildInFuncXml(value interface{}, rootTag ...string) (string, error) {
|
|
|
|
b, err := gjson.New(value).ToXml(rootTag...)
|
|
|
|
return string(b), err
|
|
|
|
}
|
|
|
|
|
|
|
|
// buildInFuncXml implements build-in template function: ini ,
|
|
|
|
// which encodes and returns `value` as XML string.
|
|
|
|
func (view *View) buildInFuncIni(value interface{}) (string, error) {
|
|
|
|
b, err := gjson.New(value).ToIni()
|
|
|
|
return string(b), err
|
|
|
|
}
|
|
|
|
|
|
|
|
// buildInFuncYaml implements build-in template function: yaml ,
|
|
|
|
// which encodes and returns `value` as YAML string.
|
|
|
|
func (view *View) buildInFuncYaml(value interface{}) (string, error) {
|
|
|
|
b, err := gjson.New(value).ToYaml()
|
|
|
|
return string(b), err
|
|
|
|
}
|
|
|
|
|
2022-01-17 17:10:44 +08:00
|
|
|
// buildInFuncYamlIndent implements build-in template function: yamli ,
|
|
|
|
// which encodes and returns `value` as YAML string with custom indent string.
|
|
|
|
func (view *View) buildInFuncYamlIndent(value, indent interface{}) (string, error) {
|
|
|
|
b, err := gjson.New(value).ToYamlIndent(gconv.String(indent))
|
|
|
|
return string(b), err
|
|
|
|
}
|
|
|
|
|
2022-01-17 15:55:45 +08:00
|
|
|
// buildInFuncToml implements build-in template function: toml ,
|
|
|
|
// which encodes and returns `value` as TOML string.
|
|
|
|
func (view *View) buildInFuncToml(value interface{}) (string, error) {
|
|
|
|
b, err := gjson.New(value).ToToml()
|
2021-09-14 19:30:20 +08:00
|
|
|
return string(b), err
|
2020-11-28 22:48:01 +08:00
|
|
|
}
|
2021-08-25 20:00:53 +08:00
|
|
|
|
|
|
|
// buildInFuncPlus implements build-in template function: plus ,
|
|
|
|
// which returns the result that pluses all `deltas` to `value`.
|
|
|
|
func (view *View) buildInFuncPlus(value interface{}, deltas ...interface{}) string {
|
|
|
|
result := gconv.Float64(value)
|
|
|
|
for _, v := range deltas {
|
|
|
|
result += gconv.Float64(v)
|
|
|
|
}
|
|
|
|
return gconv.String(result)
|
|
|
|
}
|
|
|
|
|
|
|
|
// buildInFuncMinus implements build-in template function: minus ,
|
|
|
|
// which returns the result that subtracts all `deltas` from `value`.
|
|
|
|
func (view *View) buildInFuncMinus(value interface{}, deltas ...interface{}) string {
|
|
|
|
result := gconv.Float64(value)
|
|
|
|
for _, v := range deltas {
|
|
|
|
result -= gconv.Float64(v)
|
|
|
|
}
|
|
|
|
return gconv.String(result)
|
|
|
|
}
|
|
|
|
|
|
|
|
// buildInFuncTimes implements build-in template function: times ,
|
|
|
|
// which returns the result that multiplies `value` by all of `values`.
|
|
|
|
func (view *View) buildInFuncTimes(value interface{}, values ...interface{}) string {
|
|
|
|
result := gconv.Float64(value)
|
|
|
|
for _, v := range values {
|
|
|
|
result *= gconv.Float64(v)
|
|
|
|
}
|
|
|
|
return gconv.String(result)
|
|
|
|
}
|
|
|
|
|
|
|
|
// buildInFuncDivide implements build-in template function: divide ,
|
|
|
|
// which returns the result that divides `value` by all of `values`.
|
|
|
|
func (view *View) buildInFuncDivide(value interface{}, values ...interface{}) string {
|
|
|
|
result := gconv.Float64(value)
|
|
|
|
for _, v := range values {
|
|
|
|
value2Float64 := gconv.Float64(v)
|
|
|
|
if value2Float64 == 0 {
|
|
|
|
// Invalid `value2`.
|
|
|
|
return "0"
|
|
|
|
}
|
|
|
|
result /= value2Float64
|
|
|
|
}
|
|
|
|
return gconv.String(result)
|
|
|
|
}
|