admin / template /types /display.go
AZLABS's picture
Upload folder using huggingface_hub
530729e verified
package types
import (
"fmt"
"html"
"html/template"
"strings"
"github.com/GoAdminGroup/go-admin/context"
"github.com/GoAdminGroup/go-admin/modules/config"
"github.com/GoAdminGroup/go-admin/template/types/form"
"golang.org/x/text/cases"
"golang.org/x/text/language"
)
type DisplayFnGenerator interface {
Get(ctx *context.Context, args ...interface{}) FieldFilterFn
JS() template.HTML
HTML() template.HTML
}
type BaseDisplayFnGenerator struct{}
func (base *BaseDisplayFnGenerator) JS() template.HTML { return "" }
func (base *BaseDisplayFnGenerator) HTML() template.HTML { return "" }
var displayFnGens = make(map[string]DisplayFnGenerator)
func RegisterDisplayFnGenerator(key string, gen DisplayFnGenerator) {
if _, ok := displayFnGens[key]; ok {
panic("display function generator has been registered")
}
displayFnGens[key] = gen
}
type FieldDisplay struct {
Display FieldFilterFn
DisplayProcessChains DisplayProcessFnChains
}
func (f FieldDisplay) ToDisplay(value FieldModel) interface{} {
val := f.Display(value)
if len(f.DisplayProcessChains) > 0 && f.IsNotSelectRes(val) {
valStr := fmt.Sprintf("%v", val)
for _, process := range f.DisplayProcessChains {
valStr = fmt.Sprintf("%v", process(FieldModel{
Row: value.Row,
Value: valStr,
ID: value.ID,
}))
}
return valStr
}
return val
}
func (f FieldDisplay) IsNotSelectRes(v interface{}) bool {
switch v.(type) {
case template.HTML:
return false
case []string:
return false
case [][]string:
return false
default:
return true
}
}
func (f FieldDisplay) ToDisplayHTML(value FieldModel) template.HTML {
v := f.ToDisplay(value)
if h, ok := v.(template.HTML); ok {
return h
} else if s, ok := v.(string); ok {
return template.HTML(s)
} else if arr, ok := v.([]string); ok && len(arr) > 0 {
return template.HTML(arr[0])
} else if arr, ok := v.([]template.HTML); ok && len(arr) > 0 {
return arr[0]
} else if v != nil {
return template.HTML(fmt.Sprintf("%v", v))
} else {
return ""
}
}
func (f FieldDisplay) ToDisplayString(value FieldModel) string {
v := f.ToDisplay(value)
if h, ok := v.(template.HTML); ok {
return string(h)
} else if s, ok := v.(string); ok {
return s
} else if arr, ok := v.([]string); ok && len(arr) > 0 {
return arr[0]
} else if arr, ok := v.([]template.HTML); ok && len(arr) > 0 {
return string(arr[0])
} else if v != nil {
return fmt.Sprintf("%v", v)
} else {
return ""
}
}
func (f FieldDisplay) ToDisplayStringArray(value FieldModel) []string {
v := f.ToDisplay(value)
if h, ok := v.(template.HTML); ok {
return []string{string(h)}
} else if s, ok := v.(string); ok {
return []string{s}
} else if arr, ok := v.([]string); ok && len(arr) > 0 {
return arr
} else if arr, ok := v.([]template.HTML); ok && len(arr) > 0 {
ss := make([]string, len(arr))
for k, a := range arr {
ss[k] = string(a)
}
return ss
} else if v != nil {
return []string{fmt.Sprintf("%v", v)}
} else {
return []string{}
}
}
func (f FieldDisplay) ToDisplayStringArrayArray(value FieldModel) [][]string {
v := f.ToDisplay(value)
if h, ok := v.(template.HTML); ok {
return [][]string{{string(h)}}
} else if s, ok := v.(string); ok {
return [][]string{{s}}
} else if arr, ok := v.([]string); ok && len(arr) > 0 {
return [][]string{arr}
} else if arr, ok := v.([][]string); ok && len(arr) > 0 {
return arr
} else if arr, ok := v.([]template.HTML); ok && len(arr) > 0 {
ss := make([]string, len(arr))
for k, a := range arr {
ss[k] = string(a)
}
return [][]string{ss}
} else if v != nil {
return [][]string{{fmt.Sprintf("%v", v)}}
} else {
return [][]string{}
}
}
func (f FieldDisplay) AddLimit(limit int) DisplayProcessFnChains {
return f.DisplayProcessChains.Add(func(value FieldModel) interface{} {
if limit > len(value.Value) {
return value.Value
} else if limit < 0 {
return ""
} else {
return value.Value[:limit]
}
})
}
func (f FieldDisplay) AddTrimSpace() DisplayProcessFnChains {
return f.DisplayProcessChains.Add(func(value FieldModel) interface{} {
return strings.TrimSpace(value.Value)
})
}
func (f FieldDisplay) AddSubstr(start int, end int) DisplayProcessFnChains {
return f.DisplayProcessChains.Add(func(value FieldModel) interface{} {
if start > end || start > len(value.Value) || end < 0 {
return ""
}
if start < 0 {
start = 0
}
if end > len(value.Value) {
end = len(value.Value)
}
return value.Value[start:end]
})
}
func (f FieldDisplay) AddToTitle() DisplayProcessFnChains {
return f.DisplayProcessChains.Add(func(value FieldModel) interface{} {
return cases.Title(language.Und).String(value.Value)
})
}
func (f FieldDisplay) AddToUpper() DisplayProcessFnChains {
return f.DisplayProcessChains.Add(func(value FieldModel) interface{} {
return strings.ToUpper(value.Value)
})
}
func (f FieldDisplay) AddToLower() DisplayProcessFnChains {
return f.DisplayProcessChains.Add(func(value FieldModel) interface{} {
return strings.ToLower(value.Value)
})
}
type DisplayProcessFnChains []FieldFilterFn
func (d DisplayProcessFnChains) Valid() bool {
return len(d) > 0
}
func (d DisplayProcessFnChains) Add(f FieldFilterFn) DisplayProcessFnChains {
return append(d, f)
}
func (d DisplayProcessFnChains) Append(f DisplayProcessFnChains) DisplayProcessFnChains {
return append(d, f...)
}
func (d DisplayProcessFnChains) Copy() DisplayProcessFnChains {
if len(d) == 0 {
return make(DisplayProcessFnChains, 0)
} else {
var newDisplayProcessFnChains = make(DisplayProcessFnChains, len(d))
copy(newDisplayProcessFnChains, d)
return newDisplayProcessFnChains
}
}
func chooseDisplayProcessChains(internal DisplayProcessFnChains) DisplayProcessFnChains {
if len(internal) > 0 {
return internal
}
return globalDisplayProcessChains.Copy()
}
var globalDisplayProcessChains = make(DisplayProcessFnChains, 0)
func AddGlobalDisplayProcessFn(f FieldFilterFn) {
globalDisplayProcessChains = globalDisplayProcessChains.Add(f)
}
func AddLimit(limit int) DisplayProcessFnChains {
return addLimit(limit, globalDisplayProcessChains)
}
func AddTrimSpace() DisplayProcessFnChains {
return addTrimSpace(globalDisplayProcessChains)
}
func AddSubstr(start int, end int) DisplayProcessFnChains {
return addSubstr(start, end, globalDisplayProcessChains)
}
func AddToTitle() DisplayProcessFnChains {
return addToTitle(globalDisplayProcessChains)
}
func AddToUpper() DisplayProcessFnChains {
return addToUpper(globalDisplayProcessChains)
}
func AddToLower() DisplayProcessFnChains {
return addToLower(globalDisplayProcessChains)
}
func AddXssFilter() DisplayProcessFnChains {
return addXssFilter(globalDisplayProcessChains)
}
func AddXssJsFilter() DisplayProcessFnChains {
return addXssJsFilter(globalDisplayProcessChains)
}
func addLimit(limit int, chains DisplayProcessFnChains) DisplayProcessFnChains {
chains = chains.Add(func(value FieldModel) interface{} {
if limit > len(value.Value) {
return value
} else if limit < 0 {
return ""
} else {
return value.Value[:limit]
}
})
return chains
}
func addTrimSpace(chains DisplayProcessFnChains) DisplayProcessFnChains {
chains = chains.Add(func(value FieldModel) interface{} {
return strings.TrimSpace(value.Value)
})
return chains
}
func addSubstr(start int, end int, chains DisplayProcessFnChains) DisplayProcessFnChains {
chains = chains.Add(func(value FieldModel) interface{} {
if start > end || start > len(value.Value) || end < 0 {
return ""
}
if start < 0 {
start = 0
}
if end > len(value.Value) {
end = len(value.Value)
}
return value.Value[start:end]
})
return chains
}
func addToTitle(chains DisplayProcessFnChains) DisplayProcessFnChains {
chains = chains.Add(func(value FieldModel) interface{} {
return cases.Title(language.Und).String(value.Value)
})
return chains
}
func addToUpper(chains DisplayProcessFnChains) DisplayProcessFnChains {
chains = chains.Add(func(value FieldModel) interface{} {
return strings.ToUpper(value.Value)
})
return chains
}
func addToLower(chains DisplayProcessFnChains) DisplayProcessFnChains {
chains = chains.Add(func(value FieldModel) interface{} {
return strings.ToLower(value.Value)
})
return chains
}
func addXssFilter(chains DisplayProcessFnChains) DisplayProcessFnChains {
chains = chains.Add(func(value FieldModel) interface{} {
return html.EscapeString(value.Value)
})
return chains
}
func addXssJsFilter(chains DisplayProcessFnChains) DisplayProcessFnChains {
chains = chains.Add(func(value FieldModel) interface{} {
replacer := strings.NewReplacer("<script>", "&lt;script&gt;", "</script>", "&lt;/script&gt;")
return replacer.Replace(value.Value)
})
return chains
}
func setDefaultDisplayFnOfFormType(f *FormPanel, typ form.Type) {
if typ.IsMultiFile() {
f.FieldList[f.curFieldListIndex].Display = func(value FieldModel) interface{} {
if value.Value == "" {
return ""
}
arr := strings.Split(value.Value, ",")
res := "["
for i, item := range arr {
if i == len(arr)-1 {
res += "'" + config.GetStore().URL(item) + "']"
} else {
res += "'" + config.GetStore().URL(item) + "',"
}
}
return res
}
}
if typ.IsSelect() {
f.FieldList[f.curFieldListIndex].Display = func(value FieldModel) interface{} {
return strings.Split(value.Value, ",")
}
}
}