wp-go/app/theme/wp/components.go

257 lines
7.9 KiB
Go
Raw Permalink Normal View History

2023-04-29 14:05:24 +00:00
package wp
import (
2023-05-04 12:37:06 +00:00
"github.com/fthvgb1/wp-go/app/pkg/constraints"
2023-11-12 13:39:04 +00:00
"github.com/fthvgb1/wp-go/cache/reload"
2023-04-29 14:05:24 +00:00
"github.com/fthvgb1/wp-go/helper/maps"
"github.com/fthvgb1/wp-go/helper/slice"
str "github.com/fthvgb1/wp-go/helper/strings"
"github.com/fthvgb1/wp-go/safety"
2023-04-29 14:05:24 +00:00
"strings"
)
var handleComponents = safety.NewMap[string, map[string][]Components[string]]()
2024-01-21 13:29:36 +00:00
var handleComponentHook = safety.NewMap[string, map[string][]func(Components[string]) (Components[string], bool)]()
var componentsArgs = safety.NewMap[string, any]()
var componentFilterFns = safety.NewMap[string, []func(*Handle, string, ...any) string]()
2024-01-21 13:29:36 +00:00
func (h *Handle) DeleteComponents(scene, componentKey, componentName string) {
v, ok := handleComponentHook.Load(scene)
if !ok {
v = make(map[string][]func(Components[string]) (Components[string], bool))
}
v[componentKey] = append(v[componentKey], func(c Components[string]) (Components[string], bool) {
return c, c.Name != componentName
2023-04-29 14:05:24 +00:00
})
handleComponentHook.Store(scene, v)
2023-04-29 14:05:24 +00:00
}
2024-01-21 13:29:36 +00:00
func (h *Handle) ReplaceComponents(scene, componentKey, componentName string, components Components[string]) {
v, ok := handleComponentHook.Load(scene)
if !ok {
v = make(map[string][]func(Components[string]) (Components[string], bool))
}
v[componentKey] = append(v[componentKey], func(c Components[string]) (Components[string], bool) {
if c.Name == componentName {
2023-04-29 14:05:24 +00:00
c = components
}
return c, true
})
handleComponentHook.Store(scene, v)
2023-04-29 14:05:24 +00:00
}
2024-01-21 13:29:36 +00:00
func (h *Handle) PushComponentHooks(scene, componentKey string, fn func(Components[string]) (Components[string], bool)) {
v, ok := handleComponentHook.Load(scene)
if !ok {
v = make(map[string][]func(Components[string]) (Components[string], bool))
}
v[componentKey] = append(v[componentKey], fn)
handleComponentHook.Store(scene, v)
2023-04-29 14:05:24 +00:00
}
2024-01-21 13:29:36 +00:00
var GetAndHookComponents = reload.BuildMapFnWithAnyParams[string]("calComponents", HookComponent)
2024-01-21 13:29:36 +00:00
func HookComponent(a ...any) []Components[string] {
componentKey := a[0].(string)
scene := a[1].(string)
mut := reload.GetGlobeMutex()
mut.Lock()
2024-01-21 13:29:36 +00:00
defer mut.Unlock()
components := GetComponents(scene, componentKey)
2024-01-19 07:18:55 +00:00
r := slice.FilterAndMap(components, func(component Components[string]) (Components[string], bool) {
2024-01-21 13:29:36 +00:00
keyHooks, ok := handleComponentHook.Load(scene)
if !ok {
return component, true
}
2024-01-21 13:29:36 +00:00
hooks := keyHooks[componentKey]
for _, fn := range hooks {
hookedComponent, ok := fn(component)
if !ok { // DeleteComponents fn
return hookedComponent, false
}
component = hookedComponent // ReplaceComponents fn
}
return component, true
})
slice.SimpleSort(r, slice.DESC, func(t Components[string]) float64 {
return t.Order
})
return r
}
2024-01-21 13:29:36 +00:00
func GetComponents(scene, key string) (r []Components[string]) {
sceneComponents, _ := handleComponents.Load(scene)
allSceneComponents, _ := handleComponents.Load(constraints.AllScene)
2024-01-21 13:29:36 +00:00
r = append(sceneComponents[key], allSceneComponents[key]...)
return
}
2024-01-21 13:29:36 +00:00
var CacheComponent = reload.BuildMapFnWithAnyParams[string]("cacheComponents", cacheComponentFn)
2024-01-21 13:29:36 +00:00
func cacheComponentFn(a ...any) string {
return a[0].(Components[string]).Fn(a[1].(*Handle))
}
2024-01-21 13:29:36 +00:00
func CalComponent(h *Handle) func(string) string {
return func(componentKey string) string {
cacheKey := str.Join("get-hook-Components-", h.scene, "-", componentKey)
hookedComponents := GetAndHookComponents(cacheKey, componentKey, h.scene)
var s = make([]string, 0, len(hookedComponents))
for _, component := range hookedComponents {
2023-04-29 14:05:24 +00:00
if component.Val != "" {
s = append(s, component.Val)
continue
}
if component.Fn != nil {
v := ""
if component.Cached {
2024-01-21 13:29:36 +00:00
key := str.Join(h.scene, "-", componentKey, "-", component.Name)
v = CacheComponent(key, component, h)
2023-04-29 14:05:24 +00:00
} else {
v = component.Fn(h)
}
if v != "" {
s = append(s, v)
}
}
}
2024-01-21 13:29:36 +00:00
return strings.Join(s, "\n")
2023-04-29 14:05:24 +00:00
}
}
2023-04-30 13:17:33 +00:00
func (h *Handle) PushComponents(scene, componentType string, components ...Components[string]) {
c, ok := handleComponents.Load(scene)
2023-04-30 13:17:33 +00:00
if !ok {
c = make(map[string][]Components[string])
}
c[componentType] = append(c[componentType], components...)
handleComponents.Store(scene, c)
2023-04-29 14:05:24 +00:00
}
2023-06-15 10:00:57 +00:00
func (h *Handle) PushGroupComponentStr(scene, componentType, name string, order float64, strs ...string) {
2023-06-13 04:02:46 +00:00
var component = Components[string]{
Val: strings.Join(slice.FilterAndMap(strs, func(t string) (string, bool) {
2023-06-13 04:03:52 +00:00
t = strings.Trim(t, " \n\r\t\v\x00")
2023-06-13 04:02:46 +00:00
if t == "" {
return "", false
}
return t, true
}), "\n"),
Order: order,
Name: name,
2023-04-29 14:05:24 +00:00
}
2023-06-13 04:02:46 +00:00
h.PushComponents(scene, componentType, component)
2023-04-29 14:05:24 +00:00
}
2023-06-15 10:00:57 +00:00
func (h *Handle) PushCacheGroupHeadScript(scene, name string, order float64, fns ...func(*Handle) string) {
2023-04-30 13:17:33 +00:00
h.PushGroupCacheComponentFn(scene, constraints.HeadScript, name, order, fns...)
2023-04-29 14:05:24 +00:00
}
2023-04-30 13:17:33 +00:00
func (h *Handle) PushFooterScript(scene string, components ...Components[string]) {
h.PushComponents(scene, constraints.FooterScript, components...)
2023-04-29 14:05:24 +00:00
}
2023-06-15 10:00:57 +00:00
func (h *Handle) PushGroupFooterScript(scene, name string, order float64, strs ...string) {
2023-04-30 13:17:33 +00:00
h.PushGroupComponentStr(scene, constraints.FooterScript, name, order, strs...)
2023-04-29 14:05:24 +00:00
}
2023-06-15 10:00:57 +00:00
func (h *Handle) PushCacheGroupFooterScript(scene, name string, order float64, fns ...func(*Handle) string) {
2023-04-30 13:17:33 +00:00
h.PushGroupCacheComponentFn(scene, constraints.FooterScript, name, order, fns...)
2023-04-29 14:05:24 +00:00
}
2023-06-15 10:00:57 +00:00
func (h *Handle) PushGroupCacheComponentFn(scene, componentType, name string, order float64, fns ...func(*Handle) string) {
2023-04-30 13:17:33 +00:00
h.PushComponents(scene, componentType, NewComponent(name, "", true, order, func(h *Handle) string {
2023-04-29 14:05:24 +00:00
return strings.Join(slice.Map(fns, func(t func(*Handle) string) string {
return t(h)
}), "\n")
}))
}
2023-06-15 10:00:57 +00:00
func NewComponent(name, val string, cached bool, order float64, fn func(handle *Handle) string) Components[string] {
2023-04-30 13:17:33 +00:00
return Components[string]{Fn: fn, Name: name, Cached: cached, Order: order, Val: val}
2023-04-29 14:05:24 +00:00
}
2023-06-15 10:00:57 +00:00
func (h *Handle) AddCacheComponent(scene, componentType, name string, order float64, fn func(*Handle) string) {
2023-04-30 13:17:33 +00:00
h.PushComponents(scene, componentType, NewComponent(name, "", true, order, fn))
2023-04-29 14:05:24 +00:00
}
2023-04-30 13:17:33 +00:00
func (h *Handle) PushHeadScript(scene string, components ...Components[string]) {
h.PushComponents(scene, constraints.HeadScript, components...)
2023-04-29 14:05:24 +00:00
}
2023-06-15 10:00:57 +00:00
func (h *Handle) PushGroupHeadScript(scene, name string, order float64, str ...string) {
2023-04-30 13:17:33 +00:00
h.PushGroupComponentStr(scene, constraints.HeadScript, name, order, str...)
2023-04-29 14:05:24 +00:00
}
func GetComponentsArgs[T any](k string, defaults T) T {
v, ok := componentsArgs.Load(k)
2023-04-29 14:05:24 +00:00
if ok {
vv, ok := v.(T)
if ok {
return vv
}
}
return defaults
}
func PushComponentsArgsForSlice[T any](name string, v ...T) {
val, ok := componentsArgs.Load(name)
2023-04-29 14:05:24 +00:00
if !ok {
var vv []T
vv = append(vv, v...)
componentsArgs.Store(name, vv)
2023-04-29 14:05:24 +00:00
return
}
vv, ok := val.([]T)
if ok {
vv = append(vv, v...)
componentsArgs.Store(name, vv)
2023-04-29 14:05:24 +00:00
}
}
func SetComponentsArgsForMap[K comparable, V any](name string, key K, v V) {
val, ok := componentsArgs.Load(name)
2023-04-29 14:05:24 +00:00
if !ok {
vv := make(map[K]V)
vv[key] = v
componentsArgs.Store(name, vv)
2023-04-29 14:05:24 +00:00
return
}
vv, ok := val.(map[K]V)
if ok {
vv[key] = v
componentsArgs.Store(name, vv)
2023-04-29 14:05:24 +00:00
}
}
func MergeComponentsArgsForMap[K comparable, V any](name string, m map[K]V) {
val, ok := componentsArgs.Load(name)
2023-04-29 14:05:24 +00:00
if !ok {
componentsArgs.Store(name, m)
2023-04-29 14:05:24 +00:00
return
}
vv, ok := val.(map[K]V)
if ok {
componentsArgs.Store(name, maps.Merge(vv, m))
2023-04-29 14:05:24 +00:00
}
}
func SetComponentsArgs(key string, value any) {
componentsArgs.Store(key, value)
2023-04-29 14:05:24 +00:00
}
func (h *Handle) GetComponentFilterFn(name string) ([]func(*Handle, string, ...any) string, bool) {
return componentFilterFns.Load(name)
2023-04-29 14:05:24 +00:00
}
2023-08-26 14:01:20 +00:00
func (h *Handle) AddActionFilter(name string, fns ...func(*Handle, string, ...any) string) {
v, _ := componentFilterFns.Load(name)
v = append(v, fns...)
componentFilterFns.Store(name, v)
2023-04-29 14:05:24 +00:00
}
2023-08-26 14:01:20 +00:00
func (h *Handle) DoActionFilter(name, s string, args ...any) string {
calls, ok := componentFilterFns.Load(name)
2023-04-29 14:05:24 +00:00
if ok {
return slice.Reduce(calls, func(fn func(*Handle, string, ...any) string, r string) string {
return fn(h, r, args...)
}, s)
}
return s
}