package wp import ( "github.com/fthvgb1/wp-go/app/cmd/reload" "github.com/fthvgb1/wp-go/app/pkg/constraints" "github.com/fthvgb1/wp-go/helper/maps" "github.com/fthvgb1/wp-go/helper/slice" str "github.com/fthvgb1/wp-go/helper/strings" "strings" ) func (h *Handle) DeleteComponents(scene, name string) { h.componentHook[scene] = append(h.componentHook[scene], func(c Components[string]) (Components[string], bool) { return c, c.Name != name }) } func (h *Handle) ReplaceComponents(scene, name string, components Components[string]) { h.componentHook[scene] = append(h.componentHook[scene], func(c Components[string]) (Components[string], bool) { if c.Name == name { c = components } return c, true }) } func (h *Handle) HookComponents(scene string, fn func(Components[string]) (Components[string], bool)) { h.componentHook[scene] = append(h.componentHook[scene], fn) } func CalComponents(h *Handle) { componentss := reload.GetAnyValMapBy("scene-components", str.Join("allScene-", h.scene), h, func(h *Handle) map[string][]Components[string] { return maps.MergeBy(func(k string, v1, v2 []Components[string]) ([]Components[string], bool) { vv := append(v1, v2...) return vv, vv != nil }, nil, h.components[h.scene], h.components[constraints.AllScene]) }) for k, components := range componentss { key := str.Join("calComponents-", h.scene, "-", k) key = h.ComponentFilterFnHook("calComponents", key, k) ss := reload.GetAnyValMapBy("calComponents", key, h, func(h *Handle) []Components[string] { r := slice.FilterAndMap(components, func(t Components[string]) (Components[string], bool) { fns, ok := h.componentHook[k] if !ok { return t, true } for _, fn := range fns { c, ok := fn(t) if !ok { return c, false } t = c } return t, true }) slice.Sort(r, func(i, j Components[string]) bool { return i.Order > j.Order }) return r }) var s = make([]string, 0, len(ss)) for _, component := range ss { if component.Val != "" { s = append(s, component.Val) continue } if component.Fn != nil { v := "" if component.Cached { v = reload.GetAnyValMapBy("cacheComponents", component.Name, h, component.Fn) } else { v = component.Fn(h) } if v != "" { s = append(s, v) } } } h.ginH[k] = strings.Join(s, "\n") } } func (h *Handle) PushComponents(scene, componentType string, components ...Components[string]) { c, ok := h.components[scene] if !ok { c = make(map[string][]Components[string]) h.components[scene] = c } c[componentType] = append(c[componentType], components...) } func (h *Handle) PushGroupComponentStr(scene, componentType, name string, order int, strs ...string) { var components []Components[string] for _, val := range strs { components = append(components, Components[string]{ Val: val, Order: order, Name: name, }) } h.PushComponents(scene, componentType, components...) } func (h *Handle) PushCacheGroupHeadScript(scene, name string, order int, fns ...func(*Handle) string) { h.PushGroupCacheComponentFn(scene, constraints.HeadScript, name, order, fns...) } func (h *Handle) PushFooterScript(scene string, components ...Components[string]) { h.PushComponents(scene, constraints.FooterScript, components...) } func (h *Handle) PushGroupFooterScript(scene, name string, order int, strs ...string) { h.PushGroupComponentStr(scene, constraints.FooterScript, name, order, strs...) } func (h *Handle) PushCacheGroupFooterScript(scene, name string, order int, fns ...func(*Handle) string) { h.PushGroupCacheComponentFn(scene, constraints.FooterScript, name, order, fns...) } func (h *Handle) PushGroupCacheComponentFn(scene, componentType, name string, order int, fns ...func(*Handle) string) { h.PushComponents(scene, componentType, NewComponent(name, "", true, order, func(h *Handle) string { return strings.Join(slice.Map(fns, func(t func(*Handle) string) string { return t(h) }), "\n") })) } func NewComponent(name, val string, cached bool, order int, fn func(handle *Handle) string) Components[string] { return Components[string]{Fn: fn, Name: name, Cached: cached, Order: order, Val: val} } func (h *Handle) AddCacheComponent(scene, componentType, name string, order int, fn func(*Handle) string) { h.PushComponents(scene, componentType, NewComponent(name, "", true, order, fn)) } func (h *Handle) PushHeadScript(scene string, components ...Components[string]) { h.PushComponents(scene, constraints.HeadScript, components...) } func (h *Handle) PushGroupHeadScript(scene, name string, order int, str ...string) { h.PushGroupComponentStr(scene, constraints.HeadScript, name, order, str...) } func GetComponentsArgs[T any](h *Handle, k string, defaults T) T { v, ok := h.componentsArgs[k] if ok { vv, ok := v.(T) if ok { return vv } } return defaults } func PushComponentsArgsForSlice[T any](h *Handle, name string, v ...T) { val, ok := h.componentsArgs[name] if !ok { var vv []T vv = append(vv, v...) h.componentsArgs[name] = vv return } vv, ok := val.([]T) if ok { vv = append(vv, v...) h.componentsArgs[name] = vv } } func SetComponentsArgsForMap[K comparable, V any](h *Handle, name string, key K, v V) { val, ok := h.componentsArgs[name] if !ok { vv := make(map[K]V) vv[key] = v h.componentsArgs[name] = vv return } vv, ok := val.(map[K]V) if ok { vv[key] = v h.componentsArgs[name] = vv } } func MergeComponentsArgsForMap[K comparable, V any](h *Handle, name string, m map[K]V) { val, ok := h.componentsArgs[name] if !ok { h.componentsArgs[name] = m return } vv, ok := val.(map[K]V) if ok { h.componentsArgs[name] = maps.Merge(vv, m) } } func (h *Handle) SetComponentsArgs(key string, value any) { h.componentsArgs[key] = value } func (h *Handle) ComponentFilterFn(name string) ([]func(*Handle, string, ...any) string, bool) { fn, ok := h.componentFilterFn[name] return fn, ok } func (h *Handle) PushComponentFilterFn(name string, fns ...func(*Handle, string, ...any) string) { h.componentFilterFn[name] = append(h.componentFilterFn[name], fns...) } func (h *Handle) ComponentFilterFnHook(name, s string, args ...any) string { calls, ok := h.componentFilterFn[name] if ok { return slice.Reduce(calls, func(fn func(*Handle, string, ...any) string, r string) string { return fn(h, r, args...) }, s) } return s }