optimize code, fix bug and add some comments

This commit is contained in:
xing 2024-01-18 23:29:50 +08:00
parent 8bdc53d175
commit 5e18c9babd
33 changed files with 924 additions and 599 deletions

View File

@ -10,8 +10,6 @@ func ThemeHook(scene string) func(*gin.Context) {
return func(c *gin.Context) { return func(c *gin.Context) {
t := theme.GetCurrentTemplateName() t := theme.GetCurrentTemplateName()
h := wp.NewHandle(c, scene, t) h := wp.NewHandle(c, scene, t)
h.Index = wp.NewIndexHandle(h)
h.Detail = wp.NewDetailHandle(h)
templ, _ := theme.GetTemplate(t) templ, _ := theme.GetTemplate(t)
h.SetTemplate(templ) h.SetTemplate(templ)
theme.Hook(t, h) theme.Hook(t, h)

View File

@ -19,9 +19,9 @@ func FlowLimit(maxRequestSleepNum, maxRequestNum int64, sleepTime []time.Duratio
} }
s := safety.Var[[]time.Duration]{} s := safety.Var[[]time.Duration]{}
s.Store(sleepTime) s.Store(sleepTime)
fn := func(msn, mn int64, st []time.Duration) { fn := func(sleepNum, maxNum int64, st []time.Duration) {
atomic.StoreInt64(&maxRequestSleepNum, msn) atomic.StoreInt64(&maxRequestSleepNum, sleepNum)
atomic.StoreInt64(&maxRequestNum, mn) atomic.StoreInt64(&maxRequestNum, maxNum)
s.Store(st) s.Store(st)
} }
return func(c *gin.Context) { return func(c *gin.Context) {

View File

@ -25,14 +25,25 @@ func IpLimit(num int64) (func(ctx *gin.Context), func(int64)) {
fn(num) fn(num)
return func(c *gin.Context) { return func(c *gin.Context) {
if atomic.LoadInt64(m.limitNum) <= 0 {
c.Next()
return
}
ip := c.ClientIP() ip := c.ClientIP()
s := false
m.mux.RLock() m.mux.RLock()
i, ok := m.m[ip] i, ok := m.m[ip]
m.mux.RUnlock() m.mux.RUnlock()
if !ok {
m.mux.Lock()
i = new(int64)
m.m[ip] = i
m.mux.Unlock()
}
defer func() { defer func() {
ii := atomic.LoadInt64(i) ii := atomic.LoadInt64(i)
if s && ii > 0 { if ii > 0 {
atomic.AddInt64(i, -1) atomic.AddInt64(i, -1)
if atomic.LoadInt64(i) == 0 { if atomic.LoadInt64(i) == 0 {
m.mux.Lock() m.mux.Lock()
@ -42,20 +53,12 @@ func IpLimit(num int64) (func(ctx *gin.Context), func(int64)) {
} }
}() }()
if !ok { if atomic.LoadInt64(i) >= atomic.LoadInt64(m.limitNum) {
m.mux.Lock()
i = new(int64)
m.m[ip] = i
m.mux.Unlock()
}
if atomic.LoadInt64(m.limitNum) > 0 && atomic.LoadInt64(i) >= atomic.LoadInt64(m.limitNum) {
c.Status(http.StatusForbidden) c.Status(http.StatusForbidden)
c.Abort() c.Abort()
return return
} }
atomic.AddInt64(i, 1) atomic.AddInt64(i, 1)
s = true
c.Next() c.Next()
}, fn }, fn
} }

View File

@ -39,9 +39,11 @@ func InitDb() (*safety.Var[*sqlx.DB], error) {
if preDb != nil { if preDb != nil {
_ = preDb.Close() _ = preDb.Close()
} }
showQuerySql = reload.FnVal("showQuerySql", false, func() bool { if showQuerySql == nil {
showQuerySql = reload.BuildFnVal("showQuerySql", false, func() bool {
return config.GetConfig().ShowQuerySql return config.GetConfig().ShowQuerySql
}) })
}
return safeDb, err return safeDb, err
} }

View File

@ -23,7 +23,7 @@ func configs(h *wp.Handle) {
}) })
wp.InitPipe(h) wp.InitPipe(h)
middleware.CommonMiddleware(h) middleware.CommonMiddleware(h)
h.Index.SetPageEle(plugins.TwentyFifteenPagination()) setPaginationAndRender(h)
h.PushCacheGroupHeadScript(constraints.AllScene, "CalCustomBackGround", 10.005, CalCustomBackGround) h.PushCacheGroupHeadScript(constraints.AllScene, "CalCustomBackGround", 10.005, CalCustomBackGround)
h.PushCacheGroupHeadScript(constraints.AllScene, "colorSchemeCss", 10.0056, colorSchemeCss) h.PushCacheGroupHeadScript(constraints.AllScene, "colorSchemeCss", 10.0056, colorSchemeCss)
h.CommonComponents() h.CommonComponents()
@ -39,8 +39,22 @@ func configs(h *wp.Handle) {
h.PushRender(constraints.AllScene, wp.NewHandleFn(wp.PreTemplate, 70.005, "wp.PreTemplate")) h.PushRender(constraints.AllScene, wp.NewHandleFn(wp.PreTemplate, 70.005, "wp.PreTemplate"))
} }
func setPaginationAndRender(h *wp.Handle) {
h.PushHandler(constraints.PipeRender, constraints.Detail, wp.NewHandleFn(func(hh *wp.Handle) {
d := hh.GetDetailHandle()
d.CommentRender = plugins.CommentRender()
d.CommentPageEle = plugins.TwentyFifteenCommentPagination()
}, 150, "setPaginationAndRender"))
wp.PushIndexHandler(constraints.PipeRender, h, wp.NewHandleFn(func(hh *wp.Handle) {
i := hh.GetIndexHandle()
i.SetPageEle(plugins.TwentyFifteenPagination())
}, 150, "setPaginationAndRender"))
}
func postThumb(h *wp.Handle) { func postThumb(h *wp.Handle) {
if h.Detail.Post.Thumbnail.Path != "" { d := h.GetDetailHandle()
h.Detail.Post.Thumbnail = wpconfig.Thumbnail(h.Detail.Post.Thumbnail.OriginAttachmentData, "post-thumbnail", "") if d.Post.Thumbnail.Path != "" {
d.Post.Thumbnail = wpconfig.Thumbnail(d.Post.Thumbnail.OriginAttachmentData, "post-thumbnail", "")
} }
} }

View File

@ -57,7 +57,7 @@ func configs(h *wp.Handle) {
components.WidgetArea(h) components.WidgetArea(h)
pushScripts(h) pushScripts(h)
h.PushRender(constraints.AllStats, wp.NewHandleFn(calCustomHeader, 10.005, "calCustomHeader")) h.PushRender(constraints.AllStats, wp.NewHandleFn(calCustomHeader, 10.005, "calCustomHeader"))
wp.SetComponentsArgs(h, widgets.Widget, map[string]string{ wp.SetComponentsArgs(widgets.Widget, map[string]string{
"{$before_widget}": `<section id="%s" class="%s">`, "{$before_widget}": `<section id="%s" class="%s">`,
"{$after_widget}": `</section>`, "{$after_widget}": `</section>`,
}) })
@ -67,13 +67,11 @@ func configs(h *wp.Handle) {
) )
videoHeader(h) videoHeader(h)
h.SetData("colophon", colophon) h.SetData("colophon", colophon)
h.Detail.CommentRender = commentFormat setPaginationAndRender(h)
h.Detail.CommentPageEle = commentPageEle
h.CommonComponents() h.CommonComponents()
h.Index.SetPageEle(paginate)
wp.ReplyCommentJs(h) wp.ReplyCommentJs(h)
h.PushPostPlugin(postThumbnail) h.PushPostPlugin(postThumbnail)
wp.SetComponentsArgsForMap(h, widgets.Search, "{$form}", searchForm) wp.SetComponentsArgsForMap(widgets.Search, "{$form}", searchForm)
wp.PushIndexHandler(constraints.PipeRender, h, wp.NewHandleFn(wp.IndexRender, 10.005, "wp.IndexRender")) wp.PushIndexHandler(constraints.PipeRender, h, wp.NewHandleFn(wp.IndexRender, 10.005, "wp.IndexRender"))
h.PushRender(constraints.Detail, wp.NewHandleFn(wp.DetailRender, 10.005, "wp.DetailRender")) h.PushRender(constraints.Detail, wp.NewHandleFn(wp.DetailRender, 10.005, "wp.DetailRender"))
h.PushDataHandler(constraints.Detail, wp.NewHandleFn(wp.Detail, 100.005, "wp.Detail"), wp.NewHandleFn(postThumb, 90.005, "{theme}.postThumb")) h.PushDataHandler(constraints.Detail, wp.NewHandleFn(wp.Detail, 100.005, "wp.Detail"), wp.NewHandleFn(postThumb, 90.005, "{theme}.postThumb"))
@ -81,6 +79,18 @@ func configs(h *wp.Handle) {
h.PushDataHandler(constraints.AllScene, wp.NewHandleFn(wp.PreCodeAndStats, 90.005, "wp.PreCodeAndStats")) h.PushDataHandler(constraints.AllScene, wp.NewHandleFn(wp.PreCodeAndStats, 90.005, "wp.PreCodeAndStats"))
} }
func setPaginationAndRender(h *wp.Handle) {
h.PushHandler(constraints.PipeRender, constraints.Detail, wp.NewHandleFn(func(hh *wp.Handle) {
d := hh.GetDetailHandle()
d.CommentRender = commentFormat
d.CommentPageEle = commentPageEle
}, 150, "setPaginationAndRender"))
wp.PushIndexHandler(constraints.PipeRender, h, wp.NewHandleFn(func(hh *wp.Handle) {
i := hh.GetIndexHandle()
i.SetPageEle(paginate)
}, 150, "setPaginationAndRender"))
}
var searchForm = `<form role="search" method="get" class="search-form" action="/"> var searchForm = `<form role="search" method="get" class="search-form" action="/">
<label for="search-form-1"> <label for="search-form-1">
<span class="screen-reader-text">{$label}</span> <span class="screen-reader-text">{$label}</span>
@ -101,7 +111,7 @@ func errorsHandle(h *wp.Handle) {
} }
func postThumb(h *wp.Handle) { func postThumb(h *wp.Handle) {
d := h.Detail d := h.GetDetailHandle()
if d.Post.Thumbnail.Path != "" { if d.Post.Thumbnail.Path != "" {
img := wpconfig.Thumbnail(d.Post.Thumbnail.OriginAttachmentData, "full", "", "thumbnail", "post-thumbnail") img := wpconfig.Thumbnail(d.Post.Thumbnail.OriginAttachmentData, "full", "", "thumbnail", "post-thumbnail")
img.Sizes = "100vw" img.Sizes = "100vw"

View File

@ -33,14 +33,14 @@ func (h *Handle) BodyClass() string {
case constraints.Search: case constraints.Search:
s := "search-no-results" s := "search-no-results"
if len(h.Index.Posts) > 0 { if len(h.GetIndexHandle().Posts) > 0 {
s = "search-results" s = "search-results"
} }
class = append(class, "search", s) class = append(class, "search", s)
case constraints.Category, constraints.Tag: case constraints.Category, constraints.Tag:
class = append(class, "archive", "category") class = append(class, "archive", "category")
cat := h.Index.Param.Category cat := h.GetIndexHandle().Param.Category
if cat == "" { if cat == "" {
break break
} }
@ -54,7 +54,7 @@ func (h *Handle) BodyClass() string {
case constraints.Author: case constraints.Author:
class = append(class, "archive", "author") class = append(class, "archive", "author")
author := h.Index.Param.Author author := h.GetIndexHandle().Param.Author
user, _ := cache.GetUserByName(h.C, author) user, _ := cache.GetUserByName(h.C, author)
class = append(class, str.Join("author-", number.IntToString(user.Id))) class = append(class, str.Join("author-", number.IntToString(user.Id)))
if user.DisplayName[0] != '%' { if user.DisplayName[0] != '%' {
@ -63,7 +63,7 @@ func (h *Handle) BodyClass() string {
case constraints.Detail: case constraints.Detail:
class = append(class, "post-template-default", "single", "single-post") class = append(class, "post-template-default", "single", "single-post")
class = append(class, str.Join("postid-", number.IntToString(h.Detail.Post.Id))) class = append(class, str.Join("postid-", number.IntToString(h.GetDetailHandle().Post.Id)))
if len(h.themeMods.ThemeSupport.PostFormats) > 0 { if len(h.themeMods.ThemeSupport.PostFormats) > 0 {
class = append(class, "single-format-standard") class = append(class, "single-format-standard")
} }

View File

@ -6,57 +6,106 @@ import (
"github.com/fthvgb1/wp-go/helper/maps" "github.com/fthvgb1/wp-go/helper/maps"
"github.com/fthvgb1/wp-go/helper/slice" "github.com/fthvgb1/wp-go/helper/slice"
str "github.com/fthvgb1/wp-go/helper/strings" str "github.com/fthvgb1/wp-go/helper/strings"
"github.com/fthvgb1/wp-go/safety"
"strings" "strings"
) )
var handleComponents = safety.NewMap[string, map[string][]Components[string]]()
var handleComponentHook = safety.NewMap[string, []func(Components[string]) (Components[string], bool)]()
var componentsArgs = safety.NewMap[string, any]()
var componentFilterFns = safety.NewMap[string, []func(*Handle, string, ...any) string]()
func (h *Handle) DeleteComponents(scene, name string) { func (h *Handle) DeleteComponents(scene, name string) {
h.componentHook[scene] = append(h.componentHook[scene], func(c Components[string]) (Components[string], bool) { v, _ := handleComponentHook.Load(scene)
v = append(v, func(c Components[string]) (Components[string], bool) {
return c, c.Name != name return c, c.Name != name
}) })
handleComponentHook.Store(scene, v)
} }
func (h *Handle) ReplaceComponents(scene, name string, components Components[string]) { func (h *Handle) ReplaceComponents(scene, name string, components Components[string]) {
h.componentHook[scene] = append(h.componentHook[scene], func(c Components[string]) (Components[string], bool) { v, _ := handleComponentHook.Load(scene)
v = append(v, func(c Components[string]) (Components[string], bool) {
if c.Name == name { if c.Name == name {
c = components c = components
} }
return c, true return c, true
}) })
handleComponentHook.Store(scene, v)
} }
func (h *Handle) HookComponents(scene string, fn func(Components[string]) (Components[string], bool)) { func (h *Handle) HookComponents(scene string, fn func(Components[string]) (Components[string], bool)) {
h.componentHook[scene] = append(h.componentHook[scene], fn) v, _ := handleComponentHook.Load(scene)
v = append(v, fn)
handleComponentHook.Store(scene, v)
} }
func CalComponents(h *Handle) { var getComponentFn = reload.BuildMapFn[string]("scene-components", getComponent)
componentss := reload.GetAnyValMapBy("scene-components", str.Join("allScene-", h.scene), h, func(h *Handle) (map[string][]Components[string], bool) { var hookComponentFn = reload.BuildMapFn[string]("calComponents", hookComponent)
return maps.MergeBy(func(k string, v1, v2 []Components[string]) ([]Components[string], bool) {
vv := append(v1, v2...) type componentParam struct {
return vv, vv != nil components []Components[string]
}, nil, h.components[h.scene], h.components[constraints.AllScene]), true k string
}
func hookComponent(p componentParam) []Components[string] {
mut := reload.GetGlobeMutex()
mut.Lock()
allHooks := slice.FilterAndToMap(p.components, func(t Components[string], _ int) (string, []func(Components[string]) (Components[string], bool), bool) {
fn, ok := handleComponentHook.Load(p.k)
return p.k, fn, ok
}) })
for k, components := range componentss { mut.Unlock()
key := str.Join("calComponents-", h.scene, "-", k) r := slice.FilterAndMap(p.components, func(component Components[string]) (Components[string], bool) {
ss := reload.GetAnyValMapBy("calComponents", key, h, func(h *Handle) ([]Components[string], bool) { hooks, ok := allHooks[p.k]
r := slice.FilterAndMap(components, func(t Components[string]) (Components[string], bool) {
fns, ok := h.componentHook[k]
if !ok { if !ok {
return t, true return component, true
} }
for _, fn := range fns { for _, fn := range hooks {
c, ok := fn(t) hookedComponent, ok := fn(component)
if !ok { if !ok { // DeleteComponents fn
return c, false return hookedComponent, false
} }
t = c component = hookedComponent // ReplaceComponents fn
} }
return t, true return component, true
}) })
slice.SimpleSort(r, slice.DESC, func(t Components[string]) float64 { slice.SimpleSort(r, slice.DESC, func(t Components[string]) float64 {
return t.Order return t.Order
}) })
return r, true return r
}) }
var s = make([]string, 0, len(ss))
for _, component := range ss { func getComponent(h *Handle) map[string][]Components[string] {
mut := reload.GetGlobeMutex()
mut.Lock()
sceneComponents, _ := handleComponents.Load(h.scene)
allSceneComponents, _ := handleComponents.Load(constraints.AllScene)
mut.Unlock()
return maps.MergeBy(func(k string, c1, c2 []Components[string]) ([]Components[string], bool) {
vv := append(c1, c2...)
return vv, vv != nil
}, nil, sceneComponents, allSceneComponents)
}
type cacheComponentParm[T any] struct {
Components[T]
h *Handle
}
var cacheComponentsFn = reload.BuildMapFn[string]("cacheComponents", cacheComponentFn)
func cacheComponentFn(a cacheComponentParm[string]) string {
return a.Fn(a.h)
}
func CalComponents(h *Handle) {
allComponents := getComponentFn(str.Join("allScene-", h.scene), h)
for k, components := range allComponents {
key := str.Join("calComponents-", h.scene, "-", k)
hookedComponents := hookComponentFn(key, componentParam{components, k})
var s = make([]string, 0, len(hookedComponents))
for _, component := range hookedComponents {
if component.Val != "" { if component.Val != "" {
s = append(s, component.Val) s = append(s, component.Val)
continue continue
@ -64,9 +113,7 @@ func CalComponents(h *Handle) {
if component.Fn != nil { if component.Fn != nil {
v := "" v := ""
if component.Cached { if component.Cached {
v = reload.GetAnyValMapBy("cacheComponents", component.Name, h, func(a *Handle) (string, bool) { v = cacheComponentsFn(component.Name, cacheComponentParm[string]{component, h})
return component.Fn(h), true
})
} else { } else {
v = component.Fn(h) v = component.Fn(h)
} }
@ -80,12 +127,12 @@ func CalComponents(h *Handle) {
} }
func (h *Handle) PushComponents(scene, componentType string, components ...Components[string]) { func (h *Handle) PushComponents(scene, componentType string, components ...Components[string]) {
c, ok := h.components[scene] c, ok := handleComponents.Load(scene)
if !ok { if !ok {
c = make(map[string][]Components[string]) c = make(map[string][]Components[string])
h.components[scene] = c
} }
c[componentType] = append(c[componentType], components...) c[componentType] = append(c[componentType], components...)
handleComponents.Store(scene, c)
} }
func (h *Handle) PushGroupComponentStr(scene, componentType, name string, order float64, strs ...string) { func (h *Handle) PushGroupComponentStr(scene, componentType, name string, order float64, strs ...string) {
@ -141,8 +188,8 @@ func (h *Handle) PushGroupHeadScript(scene, name string, order float64, str ...s
h.PushGroupComponentStr(scene, constraints.HeadScript, name, order, str...) h.PushGroupComponentStr(scene, constraints.HeadScript, name, order, str...)
} }
func GetComponentsArgs[T any](h *Handle, k string, defaults T) T { func GetComponentsArgs[T any](k string, defaults T) T {
v, ok := h.componentsArgs[k] v, ok := componentsArgs.Load(k)
if ok { if ok {
vv, ok := v.(T) vv, ok := v.(T)
if ok { if ok {
@ -152,60 +199,61 @@ func GetComponentsArgs[T any](h *Handle, k string, defaults T) T {
return defaults return defaults
} }
func PushComponentsArgsForSlice[T any](h *Handle, name string, v ...T) { func PushComponentsArgsForSlice[T any](name string, v ...T) {
val, ok := h.componentsArgs[name] val, ok := componentsArgs.Load(name)
if !ok { if !ok {
var vv []T var vv []T
vv = append(vv, v...) vv = append(vv, v...)
h.componentsArgs[name] = vv componentsArgs.Store(name, vv)
return return
} }
vv, ok := val.([]T) vv, ok := val.([]T)
if ok { if ok {
vv = append(vv, v...) vv = append(vv, v...)
h.componentsArgs[name] = vv componentsArgs.Store(name, vv)
} }
} }
func SetComponentsArgsForMap[K comparable, V any](h *Handle, name string, key K, v V) { func SetComponentsArgsForMap[K comparable, V any](name string, key K, v V) {
val, ok := h.componentsArgs[name] val, ok := componentsArgs.Load(name)
if !ok { if !ok {
vv := make(map[K]V) vv := make(map[K]V)
vv[key] = v vv[key] = v
h.componentsArgs[name] = vv componentsArgs.Store(name, vv)
return return
} }
vv, ok := val.(map[K]V) vv, ok := val.(map[K]V)
if ok { if ok {
vv[key] = v vv[key] = v
h.componentsArgs[name] = vv componentsArgs.Store(name, vv)
} }
} }
func MergeComponentsArgsForMap[K comparable, V any](h *Handle, name string, m map[K]V) { func MergeComponentsArgsForMap[K comparable, V any](name string, m map[K]V) {
val, ok := h.componentsArgs[name] val, ok := componentsArgs.Load(name)
if !ok { if !ok {
h.componentsArgs[name] = m componentsArgs.Store(name, m)
return return
} }
vv, ok := val.(map[K]V) vv, ok := val.(map[K]V)
if ok { if ok {
h.componentsArgs[name] = maps.Merge(vv, m) componentsArgs.Store(name, maps.Merge(vv, m))
} }
} }
func SetComponentsArgs(h *Handle, key string, value any) { func SetComponentsArgs(key string, value any) {
h.componentsArgs[key] = value componentsArgs.Store(key, value)
} }
func (h *Handle) ComponentFilterFn(name string) ([]func(*Handle, string, ...any) string, bool) { func (h *Handle) GetComponentFilterFn(name string) ([]func(*Handle, string, ...any) string, bool) {
fn, ok := h.componentFilterFn[name] return componentFilterFns.Load(name)
return fn, ok
} }
func (h *Handle) AddActionFilter(name string, fns ...func(*Handle, string, ...any) string) { func (h *Handle) AddActionFilter(name string, fns ...func(*Handle, string, ...any) string) {
h.componentFilterFn[name] = append(h.componentFilterFn[name], fns...) v, _ := componentFilterFns.Load(name)
v = append(v, fns...)
componentFilterFns.Store(name, v)
} }
func (h *Handle) DoActionFilter(name, s string, args ...any) string { func (h *Handle) DoActionFilter(name, s string, args ...any) string {
calls, ok := h.componentFilterFn[name] calls, ok := componentFilterFns.Load(name)
if ok { if ok {
return slice.Reduce(calls, func(fn func(*Handle, string, ...any) string, r string) string { return slice.Reduce(calls, func(fn func(*Handle, string, ...any) string, r string) string {
return fn(h, r, args...) return fn(h, r, args...)

View File

@ -40,7 +40,7 @@ func categoryDefaultArgs() map[string]string {
} }
} }
func parseAttr(attr map[any]any) (string, bool) { func parseAttr(attr map[any]any) string {
var attrs []string var attrs []string
class := maps.GetAnyAnyValWithDefaults(attr, "", "className") class := maps.GetAnyAnyValWithDefaults(attr, "", "className")
classes := strings.Split(class, " ") classes := strings.Split(class, " ")
@ -50,7 +50,7 @@ func parseAttr(attr map[any]any) (string, bool) {
} }
style := maps.GetAnyAnyValWithDefaults[map[any]any](attr, nil, "style", "typography") style := maps.GetAnyAnyValWithDefaults[map[any]any](attr, nil, "style", "typography")
if len(style) > 0 { if len(style) > 0 {
styless := maps.AnyAnyMap(style, func(k, v any) (string, string, bool) { styless := maps.AnyAnyMapTo(style, func(k, v any) (string, string, bool) {
kk, ok := k.(string) kk, ok := k.(string)
if !ok { if !ok {
return "", "", false return "", "", false
@ -68,15 +68,16 @@ func parseAttr(attr map[any]any) (string, bool) {
attrs = append(attrs, fmt.Sprintf(`style="%s;"`, strings.Join(styles, ";"))) attrs = append(attrs, fmt.Sprintf(`style="%s;"`, strings.Join(styles, ";")))
} }
attrs = append(attrs, fmt.Sprintf(`class="%s"`, strings.Join(classes, " "))) attrs = append(attrs, fmt.Sprintf(`class="%s"`, strings.Join(classes, " ")))
return strings.Join(attrs, " "), true return strings.Join(attrs, " ")
} }
func Category(h *wp.Handle, id string, blockParser ParserBlock) (func() string, error) { var GetCategoryAttr = reload.BuildValFn("block-category-attr", parseAttr)
counter := number.Counters[int]()
var err error var GetCategoryConf = reload.BuildValFnWithConfirm("block-category-conf", categoryConfFn, 5)
conf := reload.GetAnyValBy("block-category-conf", h, func(h *wp.Handle) (map[any]any, bool) {
func categoryConfFn(blockParser ParserBlock) (map[any]any, bool) {
var con any var con any
err = json.Unmarshal([]byte(blockParser.Attrs), &con) err := json.Unmarshal([]byte(blockParser.Attrs), &con)
if err != nil { if err != nil {
logs.Error(err, "解析category attr错误", blockParser.Attrs) logs.Error(err, "解析category attr错误", blockParser.Attrs)
return nil, false return nil, false
@ -112,7 +113,19 @@ func Category(h *wp.Handle, id string, blockParser ParserBlock) (func() string,
conf["className"] = strings.Join(classes, " ") conf["className"] = strings.Join(classes, " ")
} }
return conf, true return conf, true
}, 5) }
var GetCategoryArgs = reload.BuildValFnWithAnyParams("block-category-args", categoryArgs)
func categoryArgs(_ ...any) map[string]string {
args := wp.GetComponentsArgs(widgets.Widget, map[string]string{})
return maps.FilterZeroMerge(categoryDefaultArgs(), args)
}
func Category(h *wp.Handle, id string, blockParser ParserBlock) (func() string, error) {
counter := number.Counters[int]()
var err error
conf := GetCategoryConf(blockParser)
if err != nil { if err != nil {
return nil, err return nil, err
@ -127,10 +140,7 @@ func Category(h *wp.Handle, id string, blockParser ParserBlock) (func() string,
if maps.GetAnyAnyValWithDefaults(conf, false, "showOnlyTopLevel") { if maps.GetAnyAnyValWithDefaults(conf, false, "showOnlyTopLevel") {
h.C.Set("showOnlyTopLevel", true) h.C.Set("showOnlyTopLevel", true)
} }
args := reload.GetAnyValBys("block-category-args", h, func(h *wp.Handle) (map[string]string, bool) { args := GetCategoryArgs()
args := wp.GetComponentsArgs(h, widgets.Widget, map[string]string{})
return maps.FilterZeroMerge(categoryDefaultArgs(), args), true
})
return func() string { return func() string {
return category(h, id, counter, args, conf) return category(h, id, counter, args, conf)
@ -150,21 +160,21 @@ func category(h *wp.Handle, id string, counter number.Counter[int], args map[str
return str.Join(before, out, args["{$after_widget}"]) return str.Join(before, out, args["{$after_widget}"])
} }
func categoryUl(h *wp.Handle, categories []models.TermsMy, conf map[any]any) string { func categoryUl(h *wp.Handle, categories []models.TermsMy, confAttr map[any]any) string {
s := str.NewBuilder() s := str.NewBuilder()
li := widget.CategoryLi(h, conf, categories) li := widget.CategoryLi(h, confAttr, categories)
attrs := reload.GetAnyValBys("block-category-attr", conf, parseAttr) attrs := GetCategoryAttr(confAttr)
s.Sprintf(`<ul %s>%s</ul>`, attrs, li) s.Sprintf(`<ul %s>%s</ul>`, attrs, li)
return s.String() return s.String()
} }
func dropdown(h *wp.Handle, categories []models.TermsMy, id int, args map[string]string, conf map[any]any) string { func dropdown(h *wp.Handle, categories []models.TermsMy, id int, args map[string]string, confAttr map[any]any) string {
s := str.NewBuilder() s := str.NewBuilder()
ids := fmt.Sprintf(`wp-block-categories-%v`, id) ids := fmt.Sprintf(`wp-block-categories-%v`, id)
args = maps.Copy(args) args = maps.Copy(args)
args["{$selectId}"] = ids args["{$selectId}"] = ids
attrs := reload.GetAnyValBys("block-category-attr", conf, parseAttr) attrs := GetCategoryAttr(confAttr)
selects := widget.DropdownCategories(h, args, conf, categories) selects := widget.DropdownCategories(h, args, confAttr, categories)
s.Sprintf(`<div %s><label class="screen-reader-text" for="%s">%s</label>%s%s</div>`, attrs, ids, args["{$title}"], selects, strings.ReplaceAll(categoryDropdownScript, "{$id}", ids)) s.Sprintf(`<div %s><label class="screen-reader-text" for="%s">%s</label>%s%s</div>`, attrs, ids, args["{$title}"], selects, strings.ReplaceAll(categoryDropdownScript, "{$id}", ids))
return s.String() return s.String()
} }

View File

@ -40,12 +40,16 @@ var archivesConfig = map[any]any{
"title": "归档", "title": "归档",
} }
func Archive(h *wp.Handle, id string) string { var GetArchiveConf = BuildconfigFn(archivesConfig, "widget_archives", int64(2))
conf := configs(archivesConfig, "widget_archives", int64(2)) var GetArchiveArgs = reload.BuildValFnWithAnyParams("", archiveArgsFn)
args := reload.GetAnyValBys("widget-archive-args", h, func(h *wp.Handle) (map[string]string, bool) {
func archiveArgsFn(a ...any) map[string]string {
h := a[0].(*wp.Handle)
conf := a[1].(map[any]any)
id := a[2].(string)
archiveArgs := archiveArgs() archiveArgs := archiveArgs()
commonArgs := wp.GetComponentsArgs(h, widgets.Widget, CommonArgs()) commonArgs := wp.GetComponentsArgs(widgets.Widget, CommonArgs())
args := wp.GetComponentsArgs(h, widgets.Archive, archiveArgs) args := wp.GetComponentsArgs(widgets.Archive, archiveArgs)
args = maps.FilterZeroMerge(archiveArgs, CommonArgs(), commonArgs, args) args = maps.FilterZeroMerge(archiveArgs, CommonArgs(), commonArgs, args)
args["{$before_widget}"] = fmt.Sprintf(args["{$before_widget}"], str.Join("archives-", id), str.Join("widget widget_", "archive")) args["{$before_widget}"] = fmt.Sprintf(args["{$before_widget}"], str.Join("archives-", id), str.Join("widget widget_", "archive"))
args["{$title}"] = str.Join(args["{$before_title}"], conf["title"].(string), args["{$after_title}"]) args["{$title}"] = str.Join(args["{$before_title}"], conf["title"].(string), args["{$after_title}"])
@ -53,8 +57,12 @@ func Archive(h *wp.Handle, id string) string {
args["{$nav}"] = fmt.Sprintf(`<nav aria-label="%s">`, conf["title"].(string)) args["{$nav}"] = fmt.Sprintf(`<nav aria-label="%s">`, conf["title"].(string))
args["{$navCloser}"] = "</nav>" args["{$navCloser}"] = "</nav>"
} }
return args, true return args
}) }
func Archive(h *wp.Handle, id string) string {
conf := GetArchiveConf()
args := GetArchiveArgs(h, conf, id)
s := archiveTemplate s := archiveTemplate
if int64(1) == conf["dropdown"].(int64) { if int64(1) == conf["dropdown"].(int64) {
@ -83,11 +91,12 @@ var dropdownScript = `
func archiveDropDown(h *wp.Handle, conf map[any]any, args map[string]string, archives []models.PostArchive) string { func archiveDropDown(h *wp.Handle, conf map[any]any, args map[string]string, archives []models.PostArchive) string {
option := str.NewBuilder() option := str.NewBuilder()
option.Sprintf(`<option value="">%s</option>`, args["{$dropdown_label}"]) option.Sprintf(`<option value="">%s</option>`, args["{$dropdown_label}"])
month := strings.TrimLeft(h.Index.Param.Month, "0") i := h.GetIndexHandle()
month := strings.TrimLeft(i.Param.Month, "0")
showCount := conf["count"].(int64) showCount := conf["count"].(int64)
for _, archive := range archives { for _, archive := range archives {
sel := "" sel := ""
if h.Index.Param.Year == archive.Year && month == archive.Month { if i.Param.Year == archive.Year && month == archive.Month {
sel = "selected" sel = "selected"
} }
count := "" count := ""

View File

@ -44,12 +44,16 @@ func categoryArgs() map[string]string {
} }
} }
func Category(h *wp.Handle, id string) string { var GetCategoryConf = BuildconfigFn(categoryConfig, "widget_categories", int64(2))
conf := configs(categoryConfig, "widget_categories", int64(2))
args := reload.GetAnyValBys("widget-category-args", h, func(h *wp.Handle) (map[string]string, bool) { var GetCategoryArgs = reload.BuildValFnWithAnyParams("widget-category-args", categoryArgsFn)
commonArgs := wp.GetComponentsArgs(h, widgets.Widget, map[string]string{})
args := wp.GetComponentsArgs(h, widgets.Categories, categoryArgs()) func categoryArgsFn(a ...any) map[string]string {
h := a[0].(*wp.Handle)
conf := a[1].(map[any]any)
id := a[2].(string)
commonArgs := wp.GetComponentsArgs(widgets.Widget, map[string]string{})
args := wp.GetComponentsArgs(widgets.Categories, categoryArgs())
args = maps.FilterZeroMerge(categoryArgs(), CommonArgs(), commonArgs, args) args = maps.FilterZeroMerge(categoryArgs(), CommonArgs(), commonArgs, args)
args["{$before_widget}"] = fmt.Sprintf(args["{$before_widget}"], str.Join("categories-", id), str.Join("widget widget_", "categories")) args["{$before_widget}"] = fmt.Sprintf(args["{$before_widget}"], str.Join("categories-", id), str.Join("widget widget_", "categories"))
args["{$title}"] = str.Join(args["{$before_title}"], conf["title"].(string), args["{$after_title}"]) args["{$title}"] = str.Join(args["{$before_title}"], conf["title"].(string), args["{$after_title}"])
@ -57,9 +61,12 @@ func Category(h *wp.Handle, id string) string {
args["{$nav}"] = fmt.Sprintf(`<nav aria-label="%s">`, args["{title}"]) args["{$nav}"] = fmt.Sprintf(`<nav aria-label="%s">`, args["{title}"])
args["{$navCloser}"] = "</nav>" args["{$navCloser}"] = "</nav>"
} }
return args, true return args
}) }
func Category(h *wp.Handle, id string) string {
conf := GetCategoryConf()
args := GetCategoryArgs(h, conf, id)
t := categoryTemplate t := categoryTemplate
dropdown := conf["dropdown"].(int64) dropdown := conf["dropdown"].(int64)
categories := cache.CategoriesTags(h.C, constraints.Category) categories := cache.CategoriesTags(h.C, constraints.Category)
@ -201,8 +208,9 @@ func DropdownCategories(h *wp.Handle, args map[string]string, conf map[any]any,
s.Sprintf(` <option value="-1">%s</option> s.Sprintf(` <option value="-1">%s</option>
`, args["{$show_option_none}"]) `, args["{$show_option_none}"])
currentCategory := "" currentCategory := ""
i := h.GetIndexHandle()
if h.Scene() == constraints.Category { if h.Scene() == constraints.Category {
currentCategory = h.Index.Param.Category currentCategory = i.Param.Category
} }
showCount := conf["count"].(int64) showCount := conf["count"].(int64)
fn := func(category models.TermsMy, deep int) { fn := func(category models.TermsMy, deep int) {
@ -235,7 +243,7 @@ func DropdownCategories(h *wp.Handle, args map[string]string, conf map[any]any,
} }
func IsCategory(h *wp.Handle) (category models.TermsMy, r bool) { func IsCategory(h *wp.Handle) (category models.TermsMy, r bool) {
cate := wp.GetComponentsArgs[map[string]string](h, widgets.Categories, categoryArgs()) cate := wp.GetComponentsArgs[map[string]string](widgets.Categories, categoryArgs())
name, ok := cate["{$name}"] name, ok := cate["{$name}"]
if !ok || name == "" { if !ok || name == "" {
return return
@ -260,7 +268,7 @@ func IsCategory(h *wp.Handle) (category models.TermsMy, r bool) {
} }
func CategoryQueryName(h *wp.Handle) string { func CategoryQueryName(h *wp.Handle) string {
cate := wp.GetComponentsArgs[map[string]string](h, widgets.Categories, categoryArgs()) cate := wp.GetComponentsArgs[map[string]string](widgets.Categories, categoryArgs())
name, ok := cate["{$name}"] name, ok := cate["{$name}"]
if ok { if ok {
return name return name

View File

@ -14,9 +14,13 @@ func Fn(id string, fn func(*wp.Handle, string) string) func(h *wp.Handle) string
} }
} }
func configs[M ~map[K]V, K comparable, V any](m M, key string, a ...any) M { func configFns[K comparable, V any](m map[K]V, key string, a ...any) func(_ ...any) map[K]V {
return reload.GetAnyValBys(str.Join("widget-config-", key), key, func(_ string) (M, bool) { return func(_ ...any) map[K]V {
c := wpconfig.GetPHPArrayVal[M](key, nil, a...) c := wpconfig.GetPHPArrayVal[map[K]V](key, nil, a...)
return maps.FilterZeroMerge(maps.Copy(m), c), true return maps.FilterZeroMerge(maps.Copy(m), c)
}) }
}
func BuildconfigFn[K comparable, V any](m map[K]V, key string, a ...any) func(_ ...any) map[K]V {
return reload.BuildValFnWithAnyParams(str.Join("widget-config-", key), configFns(m, key, a...))
} }

View File

@ -21,18 +21,21 @@ var metaTemplate = `{$before_widget}
{$navCloser} {$navCloser}
{$after_widget}` {$after_widget}`
func metaArgs() map[string]string { func defaultMetaArgs() map[string]string {
return map[string]string{ return map[string]string{
"{$aria_label}": "", "{$aria_label}": "",
"{$title}": "", "{$title}": "",
} }
} }
func Meta(h *wp.Handle, id string) string { var GetMetaArgs = reload.BuildValFnWithAnyParams("widget-meta-args", ParseMetaArgs)
args := reload.GetAnyValBys("widget-meta-args", h, func(h *wp.Handle) (map[string]string, bool) {
commonArgs := wp.GetComponentsArgs(h, widgets.Widget, map[string]string{}) func ParseMetaArgs(a ...any) map[string]string {
metaArgs := metaArgs() h := a[0].(*wp.Handle)
args := wp.GetComponentsArgs(h, widgets.Meta, metaArgs) id := a[1].(string)
commonArgs := wp.GetComponentsArgs(widgets.Widget, map[string]string{})
metaArgs := defaultMetaArgs()
args := wp.GetComponentsArgs(widgets.Meta, metaArgs)
args = maps.FilterZeroMerge(metaArgs, CommonArgs(), commonArgs, args) args = maps.FilterZeroMerge(metaArgs, CommonArgs(), commonArgs, args)
args["{$before_widget}"] = fmt.Sprintf(args["{$before_widget}"], str.Join("meta-", id), str.Join("widget widget_", "meta")) args["{$before_widget}"] = fmt.Sprintf(args["{$before_widget}"], str.Join("meta-", id), str.Join("widget widget_", "meta"))
args["{$title}"] = wpconfig.GetPHPArrayVal("widget_meta", "其它操作", int64(2), "title") args["{$title}"] = wpconfig.GetPHPArrayVal("widget_meta", "其它操作", int64(2), "title")
@ -46,9 +49,11 @@ func Meta(h *wp.Handle, id string) string {
args["{$nav}"] = fmt.Sprintf(`<nav aria-label="%s">`, args["{$title}"]) args["{$nav}"] = fmt.Sprintf(`<nav aria-label="%s">`, args["{$title}"])
args["{$navCloser}"] = "</nav>" args["{$navCloser}"] = "</nav>"
} }
return args, true return args
}) }
func Meta(h *wp.Handle, id string) string {
args := GetMetaArgs(h, id)
ss := str.NewBuilder() ss := str.NewBuilder()
if str.ToInteger(wpconfig.GetOption("users_can_register"), 0) > 0 { if str.ToInteger(wpconfig.GetOption("users_can_register"), 0) > 0 {
ss.Sprintf(`<li><a href="/wp-login.php?action=register">注册</li>`) ss.Sprintf(`<li><a href="/wp-login.php?action=register">注册</li>`)

View File

@ -39,13 +39,17 @@ var recentCommentsTemplate = `{$before_widget}
{$after_widget} {$after_widget}
` `
func RecentComments(h *wp.Handle, id string) string { var GetRecentCommentConf = BuildconfigFn(recentCommentConf, "widget_recent-comments", int64(2))
conf := configs(recentCommentConf, "widget_recent-comments", int64(2))
args := reload.GetAnyValBys("widget-recent-comment-args", h, func(h *wp.Handle) (map[string]string, bool) { var GetRecentCommentArgs = reload.BuildValFnWithAnyParams("widget-recent-comment-args", RecentCommentArgs)
func RecentCommentArgs(a ...any) map[string]string {
h := a[0].(*wp.Handle)
conf := a[1].(map[any]any)
id := a[2].(string)
commentsArgs := recentCommentsArgs() commentsArgs := recentCommentsArgs()
commonArgs := wp.GetComponentsArgs(h, widgets.Widget, map[string]string{}) commonArgs := wp.GetComponentsArgs(widgets.Widget, map[string]string{})
args := wp.GetComponentsArgs(h, widgets.RecentComments, commentsArgs) args := wp.GetComponentsArgs(widgets.RecentComments, commentsArgs)
args = maps.FilterZeroMerge(commentsArgs, CommonArgs(), commonArgs, args) args = maps.FilterZeroMerge(commentsArgs, CommonArgs(), commonArgs, args)
args["{$before_widget}"] = fmt.Sprintf(args["{$before_widget}"], str.Join("recent-comments-", id), str.Join("widget widget_", "recent_comments")) args["{$before_widget}"] = fmt.Sprintf(args["{$before_widget}"], str.Join("recent-comments-", id), str.Join("widget widget_", "recent_comments"))
args["{$title}"] = str.Join(args["{$before_title}"], conf["title"].(string), args["{$after_title}"]) args["{$title}"] = str.Join(args["{$before_title}"], conf["title"].(string), args["{$after_title}"])
@ -53,8 +57,11 @@ func RecentComments(h *wp.Handle, id string) string {
args["{$nav}"] = fmt.Sprintf(`<nav aria-label="%s">`, conf["title"]) args["{$nav}"] = fmt.Sprintf(`<nav aria-label="%s">`, conf["title"])
args["{$navCloser}"] = "</nav>" args["{$navCloser}"] = "</nav>"
} }
return args, true return args
}) }
func RecentComments(h *wp.Handle, id string) string {
conf := GetRecentCommentConf()
args := GetRecentCommentArgs(h, conf, id)
comments := slice.Map(cache.RecentComments(h.C, int(conf["number"].(int64))), func(t models.Comments) string { comments := slice.Map(cache.RecentComments(h.C, int(conf["number"].(int64))), func(t models.Comments) string {
return fmt.Sprintf(` <li> return fmt.Sprintf(` <li>

View File

@ -25,7 +25,7 @@ var recentPostsTemplate = `{$before_widget}
{$after_widget} {$after_widget}
` `
func recentPostsArgs() map[string]string { func DefaultRecentPostsArgs() map[string]string {
return map[string]string{ return map[string]string{
"{$before_sidebar}": "", "{$before_sidebar}": "",
"{$after_sidebar}": "", "{$after_sidebar}": "",
@ -35,7 +35,7 @@ func recentPostsArgs() map[string]string {
} }
} }
func recentConf() map[any]any { func DefaultRecentConf() map[any]any {
return map[any]any{ return map[any]any{
"number": int64(5), "number": int64(5),
"show_date": false, "show_date": false,
@ -43,18 +43,24 @@ func recentConf() map[any]any {
} }
} }
func RecentPosts(h *wp.Handle, id string) string { var GetRecentPostConf = reload.BuildValFnWithAnyParams("widget-recent-posts-conf", RecentPostConf)
conf := reload.GetAnyValBys("widget-recent-posts-conf", h, func(h *wp.Handle) (map[any]any, bool) {
recent := recentConf() func RecentPostConf(_ ...any) map[any]any {
recent := DefaultRecentConf()
conf := wpconfig.GetPHPArrayVal[map[any]any]("widget_recent-posts", recent, int64(2)) conf := wpconfig.GetPHPArrayVal[map[any]any]("widget_recent-posts", recent, int64(2))
conf = maps.FilterZeroMerge(recent, conf) conf = maps.FilterZeroMerge(recent, conf)
return conf, true return conf
}) }
args := reload.GetAnyValBys("widget-recent-posts-args", h, func(h *wp.Handle) (map[string]string, bool) { var GetRecentPostArgs = reload.BuildValFnWithAnyParams("widget-recent-posts-args", ParseRecentPostArgs)
recent := recentPostsArgs()
commonArgs := wp.GetComponentsArgs(h, widgets.Widget, map[string]string{}) func ParseRecentPostArgs(a ...any) map[string]string {
args := wp.GetComponentsArgs(h, widgets.RecentPosts, recent) h := a[0].(*wp.Handle)
conf := a[1].(map[any]any)
id := a[2].(string)
recent := DefaultRecentPostsArgs()
commonArgs := wp.GetComponentsArgs(widgets.Widget, map[string]string{})
args := wp.GetComponentsArgs(widgets.RecentPosts, recent)
args = maps.FilterZeroMerge(recent, CommonArgs(), commonArgs, args) args = maps.FilterZeroMerge(recent, CommonArgs(), commonArgs, args)
args["{$before_widget}"] = fmt.Sprintf(args["{$before_widget}"], str.Join("recent-posts-", id), str.Join("widget widget_", "recent_entries")) args["{$before_widget}"] = fmt.Sprintf(args["{$before_widget}"], str.Join("recent-posts-", id), str.Join("widget widget_", "recent_entries"))
args["{$title}"] = str.Join(args["{$before_title}"], conf["title"].(string), args["{$after_title}"]) args["{$title}"] = str.Join(args["{$before_title}"], conf["title"].(string), args["{$after_title}"])
@ -62,9 +68,12 @@ func RecentPosts(h *wp.Handle, id string) string {
args["{$nav}"] = fmt.Sprintf(`<nav aria-label="%s">`, conf["title"]) args["{$nav}"] = fmt.Sprintf(`<nav aria-label="%s">`, conf["title"])
args["{$navCloser}"] = "</nav>" args["{$navCloser}"] = "</nav>"
} }
return args, true return args
}) }
func RecentPosts(h *wp.Handle, id string) string {
conf := GetRecentPostConf()
args := GetRecentPostArgs(h, conf, id)
currentPostId := uint64(0) currentPostId := uint64(0)
if h.Scene() == constraints.Detail { if h.Scene() == constraints.Detail {
currentPostId = str.ToInteger(h.C.Param("id"), uint64(0)) currentPostId = str.ToInteger(h.C.Param("id"), uint64(0))

View File

@ -47,11 +47,14 @@ func searchArgs() map[string]string {
var form = html5SearchForm var form = html5SearchForm
func Search(h *wp.Handle, id string) string { var GetSearchArgs = reload.BuildValFnWithAnyParams("widget-search-args", ParseSearchArgs)
args := reload.GetAnyValBys("widget-search-args", h, func(h *wp.Handle) (map[string]string, bool) {
func ParseSearchArgs(a ...any) map[string]string {
h := a[0].(*wp.Handle)
id := a[1].(string)
search := searchArgs() search := searchArgs()
commonArgs := wp.GetComponentsArgs(h, widgets.Widget, map[string]string{}) commonArgs := wp.GetComponentsArgs(widgets.Widget, map[string]string{})
args := wp.GetComponentsArgs(h, widgets.Search, search) args := wp.GetComponentsArgs(widgets.Search, search)
args = maps.FilterZeroMerge(search, CommonArgs(), commonArgs, args) args = maps.FilterZeroMerge(search, CommonArgs(), commonArgs, args)
args["{$before_widget}"] = fmt.Sprintf(args["{$before_widget}"], str.Join("search-", id), str.Join("widget widget_", "search")) args["{$before_widget}"] = fmt.Sprintf(args["{$before_widget}"], str.Join("search-", id), str.Join("widget widget_", "search"))
if args["{$title}"] == "" { if args["{$title}"] == "" {
@ -69,12 +72,15 @@ func Search(h *wp.Handle, id string) string {
form = xmlSearchForm form = xmlSearchForm
} }
return args, true return args
}) }
func Search(h *wp.Handle, id string) string {
args := GetSearchArgs(h, id)
s := strings.ReplaceAll(searchTemplate, "{$form}", form) s := strings.ReplaceAll(searchTemplate, "{$form}", form)
val := "" val := ""
if h.Scene() == constraints.Search { if h.Scene() == constraints.Search {
val = html.SpecialChars(h.Index.Param.Search) val = html.SpecialChars(h.GetIndexHandle().Param.Search)
} }
s = strings.ReplaceAll(s, "{$value}", val) s = strings.ReplaceAll(s, "{$value}", val)
return h.DoActionFilter(widgets.Search, str.Replace(s, args)) return h.DoActionFilter(widgets.Search, str.Replace(s, args))

View File

@ -18,16 +18,21 @@ func (h *Handle) DisplayHeaderText() bool {
return h.themeMods.ThemeSupport.CustomHeader.HeaderText && "blank" != h.themeMods.HeaderTextcolor return h.themeMods.ThemeSupport.CustomHeader.HeaderText && "blank" != h.themeMods.HeaderTextcolor
} }
func (h *Handle) GetCustomHeaderImg() (r models.PostThumbnail, isRand bool) { var GetCustomHeaderImgFn = reload.BuildValFnWithConfirm("headerImages", customHeadImag, 5)
var err error
img := reload.GetAnyValBy("headerImages", h.theme, func(theme string) ([]models.PostThumbnail, bool) { func customHeadImag(h *Handle) ([]models.PostThumbnail, bool) {
hs, er := h.GetHeaderImages(h.theme) hs, err := h.GetHeaderImages(h.theme)
if er != nil { if err != nil {
err = er h.SetErr(err)
return nil, false return nil, false
} }
return hs, true return hs, true
}, 5) }
func (h *Handle) GetCustomHeaderImg() (r models.PostThumbnail, isRand bool) {
var err error
img := GetCustomHeaderImgFn(h)
err = h.Err()
if err != nil { if err != nil {
logs.Error(err, "获取页眉背景图失败") logs.Error(err, "获取页眉背景图失败")
return return

View File

@ -42,10 +42,10 @@ func CalCustomLogo(h *Handle) (r string) {
return return
} }
var GetCustomLog = reload.BuildValFn("customLogo", CalCustomLogo)
func customLogo(h *Handle) func() string { func customLogo(h *Handle) func() string {
return func() string { return func() string {
return reload.GetAnyValBys("customLogo", h, func(h *Handle) (string, bool) { return GetCustomLog(h)
return CalCustomLogo(h), true
})
} }
} }

View File

@ -78,6 +78,15 @@ func (d *DetailHandle) PasswordProject() {
} }
} }
} }
func (h *Handle) GetDetailHandle() *DetailHandle {
v, ok := h.C.Get("detailHandle")
if !ok {
vv := NewDetailHandle(h)
h.C.Set("detailHandle", vv)
return vv
}
return v.(*DetailHandle)
}
func (d *DetailHandle) CommentData() { func (d *DetailHandle) CommentData() {
d.ginH["totalCommentNum"] = 0 d.ginH["totalCommentNum"] = 0
d.ginH["totalCommentPage"] = 1 d.ginH["totalCommentPage"] = 1
@ -170,16 +179,17 @@ func DetailRender(h *Handle) {
if h.Stats != constraints.Ok { if h.Stats != constraints.Ok {
return return
} }
d := h.Detail d := h.GetDetailHandle()
d.PasswordProject() d.PasswordProject()
d.RenderComment() d.RenderComment()
d.ginH["post"] = d.Post d.ginH["post"] = d.Post
} }
func Detail(h *Handle) { func Detail(h *Handle) {
err := h.Detail.BuildDetailData() d := h.GetDetailHandle()
err := d.BuildDetailData()
if err != nil { if err != nil {
h.Detail.SetErr(err) d.SetErr(err)
} }
h.SetData("scene", h.Scene()) h.SetData("scene", h.Scene())
} }
@ -187,7 +197,7 @@ func Detail(h *Handle) {
func ReplyCommentJs(h *Handle) { func ReplyCommentJs(h *Handle) {
h.PushFooterScript(constraints.Detail, NewComponent("comment-reply.js", "", false, 10, func(h *Handle) string { h.PushFooterScript(constraints.Detail, NewComponent("comment-reply.js", "", false, 10, func(h *Handle) string {
reply := "" reply := ""
if h.Detail.Post.CommentStatus == "open" && wpconfig.GetOption("thread_comments") == "1" { if h.GetDetailHandle().Post.CommentStatus == "open" && wpconfig.GetOption("thread_comments") == "1" {
reply = `<script src='/wp-includes/js/comment-reply.min.js' id='comment-reply-js'></script>` reply = `<script src='/wp-includes/js/comment-reply.min.js' id='comment-reply-js'></script>`
} }
return reply return reply

View File

@ -25,6 +25,16 @@ type IndexHandle struct {
postsPlugin PostsPlugin postsPlugin PostsPlugin
} }
func (h *Handle) GetIndexHandle() *IndexHandle {
v, ok := h.C.Get("indexHandle")
if !ok {
vv := NewIndexHandle(h)
h.C.Set("indexHandle", vv)
return vv
}
return v.(*IndexHandle)
}
func (i *IndexHandle) ListPlugin() func(*Handle, *models.Posts) { func (i *IndexHandle) ListPlugin() func(*Handle, *models.Posts) {
return i.postsPlugin return i.postsPlugin
} }
@ -120,8 +130,11 @@ func (i *IndexHandle) Pagination() {
} }
func (i *IndexHandle) BuildIndexData(parm *IndexParams) (err error) { func (i *IndexHandle) BuildIndexData() (err error) {
err = i.ParseIndex(parm) if i.Param == nil {
i.Param = NewIndexParams(i.C)
}
err = i.ParseIndex(i.Param)
if err != nil { if err != nil {
i.Stats = constraints.ParamError i.Stats = constraints.ParamError
return return
@ -137,12 +150,12 @@ func (i *IndexHandle) BuildIndexData(parm *IndexParams) (err error) {
return return
} }
var GetPostsPlugin = reload.BuildValFnWithAnyParams("postPlugins", UsePostsPlugins)
func (i *IndexHandle) ExecPostsPlugin() { func (i *IndexHandle) ExecPostsPlugin() {
fn := i.postsPlugin fn := i.postsPlugin
if fn == nil { if fn == nil {
fn = reload.GetAnyValBys("postPlugins", i, func(a *IndexHandle) (PostsPlugin, bool) { fn = GetPostsPlugin()
return UsePostsPlugins(), true
})
} }
for j := range i.Posts { for j := range i.Posts {
fn(i.Handle, &i.Posts[j]) fn(i.Handle, &i.Posts[j])
@ -150,15 +163,15 @@ func (i *IndexHandle) ExecPostsPlugin() {
} }
func IndexRender(h *Handle) { func IndexRender(h *Handle) {
i := h.Index i := h.GetIndexHandle()
i.ExecPostsPlugin() i.ExecPostsPlugin()
i.Pagination() i.Pagination()
i.ginH["posts"] = i.Posts i.ginH["posts"] = i.Posts
} }
func Index(h *Handle) { func Index(h *Handle) {
i := h.Index i := h.GetIndexHandle()
err := i.BuildIndexData(NewIndexParams(i.C)) err := i.BuildIndexData()
if err != nil { if err != nil {
i.SetErr(err) i.SetErr(err)
} }
@ -166,11 +179,11 @@ func Index(h *Handle) {
} }
func (i *IndexHandle) MarkSticky(posts *[]models.Posts) { func (i *IndexHandle) MarkSticky(posts *[]models.Posts) {
a := i.StickPosts() a := GetStickPosts(i.Handle)
if len(a) < 1 { if len(a) < 1 {
return return
} }
m := i.StickMapPosts() m := GetStickMapPosts(i.Handle)
*posts = append(a, slice.Filter(*posts, func(post models.Posts, _ int) bool { *posts = append(a, slice.Filter(*posts, func(post models.Posts, _ int) bool {
_, ok := m[post.Id] _, ok := m[post.Id]
return !ok return !ok

View File

@ -69,7 +69,7 @@ func PostPlugin(calls ...PostsPlugin) PostsPlugin {
} }
} }
func UsePostsPlugins() PostsPlugin { func UsePostsPlugins(_ ...any) PostsPlugin {
m := pluginFns.Load() m := pluginFns.Load()
pluginss := slice.FilterAndMap(config.GetConfig().ListPagePlugins, func(t string) (func(PostsPlugin, *Handle, *models.Posts), bool) { pluginss := slice.FilterAndMap(config.GetConfig().ListPagePlugins, func(t string) (func(PostsPlugin, *Handle, *models.Posts), bool) {
f, ok := m[t] f, ok := m[t]

View File

@ -71,14 +71,7 @@ var plainRouteParam = reload.Vars([]Plain{
if u == "" { if u == "" {
return false return false
} }
users := reload.GetAnyValBys("usersIds", struct{}{}, users := GetUsersIds(h)
func(_ struct{}) (map[uint64]string, bool) {
users, err := cache.GetAllUsername(h.C)
if err != nil {
return nil, true
}
return maps.Flip(users), true
})
name, ok := users[str.ToInteger[uint64](u, 0)] name, ok := users[str.ToInteger[uint64](u, 0)]
if !ok { if !ok {
return false return false
@ -90,6 +83,14 @@ var plainRouteParam = reload.Vars([]Plain{
}, },
}) })
var GetUsersIds = reload.BuildValFnWithConfirm("usersIds", func(h *wp.Handle) (map[uint64]string, bool) {
users, err := cache.GetAllUsername(h.C)
if err != nil {
return nil, false
}
return maps.Flip(users), true
}, 10)
func SetExplainRouteParam(p []Plain) { func SetExplainRouteParam(p []Plain) {
plainRouteParam.Store(p) plainRouteParam.Store(p)
} }

View File

@ -3,7 +3,6 @@ package wp
import ( import (
"github.com/fthvgb1/wp-go/app/pkg/constraints" "github.com/fthvgb1/wp-go/app/pkg/constraints"
"github.com/fthvgb1/wp-go/cache/reload" "github.com/fthvgb1/wp-go/cache/reload"
"github.com/fthvgb1/wp-go/helper"
"github.com/fthvgb1/wp-go/helper/slice" "github.com/fthvgb1/wp-go/helper/slice"
str "github.com/fthvgb1/wp-go/helper/strings" str "github.com/fthvgb1/wp-go/helper/strings"
) )
@ -52,10 +51,12 @@ func (h *Handle) ReplacePipe(scene, pipeName string, pipe Pipe) error {
} }
func (h *Handle) PushHandler(pipScene string, scene string, fns ...HandleCall) { func (h *Handle) PushHandler(pipScene string, scene string, fns ...HandleCall) {
if _, ok := h.handlers[pipScene]; !ok { v, ok := handlerss.Load(pipScene)
h.handlers[pipScene] = make(map[string][]HandleCall) if !ok {
v = make(map[string][]HandleCall)
} }
h.handlers[pipScene][scene] = append(h.handlers[pipScene][scene], fns...) v[scene] = append(v[scene], fns...)
handlerss.Store(pipScene, v)
} }
func (h *Handle) PushRender(statsOrScene string, fns ...HandleCall) { func (h *Handle) PushRender(statsOrScene string, fns ...HandleCall) {
@ -65,27 +66,14 @@ func (h *Handle) PushDataHandler(scene string, fns ...HandleCall) {
h.PushHandler(constraints.PipeData, scene, fns...) h.PushHandler(constraints.PipeData, scene, fns...)
} }
func BuildPipe(pipeScene string, keyFn func(*Handle, string) string, fn func(*Handle, map[string][]HandleCall, string) []HandleCall) func(HandleFn[*Handle], *Handle) { func BuildHandlers(pipeScene string, keyFn func(*Handle, string) string,
fn func(*Handle, map[string][]HandleCall, string) []HandleCall) func(HandleFn[*Handle], *Handle) {
pipeHandlerFn := reload.BuildMapFn[string]("pipeHandlers", BuildHandler(pipeScene, keyFn, fn))
return func(next HandleFn[*Handle], h *Handle) { return func(next HandleFn[*Handle], h *Handle) {
key := keyFn(h, pipeScene) key := keyFn(h, pipeScene)
handlers := reload.GetAnyValMapBy("pipeHandlers", key, h, func(h *Handle) ([]HandleCall, bool) { handlers := pipeHandlerFn(key, h)
conf := h.handleHook[pipeScene]
calls := fn(h, h.handlers[pipeScene], key)
calls = slice.FilterAndMap(calls, func(call HandleCall) (HandleCall, bool) {
ok := true
for _, hook := range conf {
call, ok = hook(call)
if !ok {
break
}
}
return call, ok
})
slice.SimpleSort(calls, slice.DESC, func(t HandleCall) float64 {
return t.Order
})
return calls, true
})
for _, handler := range handlers { for _, handler := range handlers {
handler.Fn(h) handler.Fn(h)
if h.abort { if h.abort {
@ -98,25 +86,58 @@ func BuildPipe(pipeScene string, keyFn func(*Handle, string) string, fn func(*Ha
} }
} }
func BuildHandler(pipeScene string, keyFn func(*Handle, string) string,
fn func(*Handle, map[string][]HandleCall, string) []HandleCall) func(*Handle) []HandleCall {
return func(h *Handle) []HandleCall {
key := keyFn(h, pipeScene)
mut := reload.GetGlobeMutex()
mut.Lock()
hookers, _ := handleHooks.Load(pipeScene)
hh, _ := handlerss.Load(pipeScene)
mut.Unlock()
calls := fn(h, hh, key)
calls = slice.FilterAndMap(calls, func(call HandleCall) (HandleCall, bool) {
ok := true
for _, hook := range hookers {
call, ok = hook(call)
if !ok {
break
}
}
return call, ok
})
slice.SimpleSort(calls, slice.DESC, func(t HandleCall) float64 {
return t.Order
})
return calls
}
}
func PipeKey(h *Handle, pipScene string) string { func PipeKey(h *Handle, pipScene string) string {
key := str.Join("pipekey", "-", pipScene, "-", h.scene, "-", h.Stats) key := str.Join("pipekey", "-", pipScene, "-", h.scene, "-", h.Stats)
return h.DoActionFilter("pipeKey", key, pipScene) return h.DoActionFilter("pipeKey", key, pipScene)
} }
var pipeInitFn = reload.BuildMapFn[string]("pipeInit", BuildPipe)
func Run(h *Handle, conf func(*Handle)) { func Run(h *Handle, conf func(*Handle)) {
if !helper.GetContextVal(h.C, "inited", false) { if !h.isInited {
InitHandle(conf, h) InitHandle(conf, h)
} }
reload.GetAnyValBys(str.Join("pipeInit-", h.scene), h, BuildPipeAndHandler)(h) pipeInitFn(h.scene, h.scene)(h)
} }
func BuildPipeAndHandler(h *Handle) (func(*Handle), bool) { func BuildPipe(scene string) func(*Handle) {
p := GetFn[Pipe]("pipe", constraints.AllScene) pipees := GetFn[Pipe]("pipe", constraints.AllScene)
p = append(p, GetFn[Pipe]("pipe", h.scene)...) pipees = append(pipees, GetFn[Pipe]("pipe", scene)...)
pipes := slice.FilterAndMap(p, func(pipe Pipe) (Pipe, bool) { pipes := slice.FilterAndMap(pipees, func(pipe Pipe) (Pipe, bool) {
var ok bool var ok bool
mut := reload.GetGlobeMutex()
mut.Lock()
hooks := GetFnHook[func(Pipe) (Pipe, bool)]("pipeHook", constraints.AllScene) hooks := GetFnHook[func(Pipe) (Pipe, bool)]("pipeHook", constraints.AllScene)
hooks = append(hooks, GetFnHook[func(Pipe) (Pipe, bool)]("pipeHook", h.scene)...) hooks = append(hooks, GetFnHook[func(Pipe) (Pipe, bool)]("pipeHook", scene)...)
mut.Unlock()
for _, fn := range hooks { for _, fn := range hooks {
pipe, ok = fn(pipe) pipe, ok = fn(pipe)
if !ok { if !ok {
@ -132,7 +153,7 @@ func BuildPipeAndHandler(h *Handle) (func(*Handle), bool) {
arr := slice.Map(pipes, func(t Pipe) HandlePipeFn[*Handle] { arr := slice.Map(pipes, func(t Pipe) HandlePipeFn[*Handle] {
return t.Fn return t.Fn
}) })
return HandlePipe(NothingToDo, arr...), true return HandlePipe(NothingToDo, arr...)
} }
func MiddlewareKey(h *Handle, pipScene string) string { func MiddlewareKey(h *Handle, pipScene string) string {
@ -164,24 +185,30 @@ func PipeRender(h *Handle, renders map[string][]HandleCall, key string) (handler
// DeleteHandle 写插件的时候用 // DeleteHandle 写插件的时候用
func (h *Handle) DeleteHandle(pipeScene string, name string) { func (h *Handle) DeleteHandle(pipeScene string, name string) {
h.handleHook[pipeScene] = append(h.handleHook[pipeScene], func(call HandleCall) (HandleCall, bool) { v, _ := handleHooks.Load(pipeScene)
v = append(v, func(call HandleCall) (HandleCall, bool) {
return call, name != call.Name return call, name != call.Name
}) })
handleHooks.Store(pipeScene, v)
} }
// ReplaceHandle 写插件的时候用 // ReplaceHandle 写插件的时候用
func (h *Handle) ReplaceHandle(pipeScene, name string, fn HandleFn[*Handle]) { func (h *Handle) ReplaceHandle(pipeScene, name string, fn HandleFn[*Handle]) {
h.handleHook[pipeScene] = append(h.handleHook[pipeScene], func(call HandleCall) (HandleCall, bool) { v, _ := handleHooks.Load(pipeScene)
v = append(v, func(call HandleCall) (HandleCall, bool) {
if name == call.Name { if name == call.Name {
call.Fn = fn call.Fn = fn
} }
return call, true return call, true
}) })
handleHooks.Store(pipeScene, v)
} }
// HookHandle 写插件的时候用 // HookHandle 写插件的时候用
func (h *Handle) HookHandle(pipeScene string, hook func(HandleCall) (HandleCall, bool)) { func (h *Handle) HookHandle(pipeScene string, hook func(HandleCall) (HandleCall, bool)) {
h.handleHook[pipeScene] = append(h.handleHook[pipeScene], hook) v, _ := handleHooks.Load(pipeScene)
v = append(v, hook)
handleHooks.Store(pipeScene, v)
} }
func (h *Handle) PushPipeHandleHook(name string, fn ...func([]HandleCall) []HandleCall) error { func (h *Handle) PushPipeHandleHook(name string, fn ...func([]HandleCall) []HandleCall) error {
@ -197,10 +224,10 @@ func (h *Handle) PipeHandleHook(name string, calls []HandleCall, m map[string][]
func InitPipe(h *Handle) { func InitPipe(h *Handle) {
h.PushPipe(constraints.AllScene, NewPipe(constraints.PipeMiddleware, 300, h.PushPipe(constraints.AllScene, NewPipe(constraints.PipeMiddleware, 300,
BuildPipe(constraints.PipeMiddleware, MiddlewareKey, PipeMiddlewareHandle))) BuildHandlers(constraints.PipeMiddleware, MiddlewareKey, PipeMiddlewareHandle)))
h.PushPipe(constraints.AllScene, NewPipe(constraints.PipeData, 200, h.PushPipe(constraints.AllScene, NewPipe(constraints.PipeData, 200,
BuildPipe(constraints.PipeData, PipeKey, PipeDataHandle))) BuildHandlers(constraints.PipeData, PipeKey, PipeDataHandle)))
h.PushPipe(constraints.AllScene, NewPipe(constraints.PipeRender, 100, h.PushPipe(constraints.AllScene, NewPipe(constraints.PipeRender, 100,
BuildPipe(constraints.PipeRender, PipeKey, PipeRender))) BuildHandlers(constraints.PipeRender, PipeKey, PipeRender)))
} }

View File

@ -70,11 +70,10 @@ func Hook(path string, fn func(Route) Route) {
return r, path == r.Path return r, path == r.Path
}) })
} }
func ResolveRoute(h *wp.Handle) {
requestURI := h.C.Request.RequestURI var RegRouteFn = reload.BuildValFnWithAnyParams("regexRoute", RegRouteHook)
rs, rrs := reload.GetAnyValBys("route",
struct{}{}, func RegRouteHook(_ ...any) func() (map[string]Route, map[string]*regexp.Regexp) {
func(_ struct{}) (func() (map[string]Route, map[string]*regexp.Regexp), bool) {
m := map[string]Route{} m := map[string]Route{}
rrs := map[string]*regexp.Regexp{} rrs := map[string]*regexp.Regexp{}
routes.Range(func(key string, value Route) bool { routes.Range(func(key string, value Route) bool {
@ -102,17 +101,20 @@ func ResolveRoute(h *wp.Handle) {
m[key] = value m[key] = value
rrs[key] = vv rrs[key] = vv
} }
return true return true
}) })
return func() (map[string]Route, map[string]*regexp.Regexp) { return func() (map[string]Route, map[string]*regexp.Regexp) {
return m, rrs return m, rrs
}, true }
})() }
func ResolveRoute(h *wp.Handle) {
requestURI := h.C.Request.RequestURI
rs, rrs := RegRouteFn()()
v, ok := rs[requestURI] v, ok := rs[requestURI]
if ok && slice.IsContained(v.Method, h.C.Request.Method) { if ok && slice.IsContained(v.Method, h.C.Request.Method) {
h.SetScene(v.Scene) h.SetScene(v.Scene)
wp.Run(h, nil) wp.Run(h, nil)
h.Abort()
return return
} }
for path, reg := range rrs { for path, reg := range rrs {
@ -125,6 +127,7 @@ func ResolveRoute(h *wp.Handle) {
h.SetScene(rr.Scene) h.SetScene(rr.Scene)
h.C.Set("route", r) h.C.Set("route", r)
wp.Run(h, nil) wp.Run(h, nil)
h.Abort()
return return
} }
} }

View File

@ -8,13 +8,13 @@ import (
"github.com/fthvgb1/wp-go/app/pkg/models" "github.com/fthvgb1/wp-go/app/pkg/models"
"github.com/fthvgb1/wp-go/app/wpconfig" "github.com/fthvgb1/wp-go/app/wpconfig"
"github.com/fthvgb1/wp-go/cache/reload" "github.com/fthvgb1/wp-go/cache/reload"
"github.com/fthvgb1/wp-go/helper/maps"
"github.com/fthvgb1/wp-go/helper/slice" "github.com/fthvgb1/wp-go/helper/slice"
str "github.com/fthvgb1/wp-go/helper/strings" str "github.com/fthvgb1/wp-go/helper/strings"
) )
func (h *Handle) StickPosts() []models.Posts { var GetStickPosts = reload.BuildValFnWithConfirm("stickPostsSlice", ParseStickPosts)
return reload.GetAnyValBys("stickPostsSlice", h, func(h *Handle) (r []models.Posts, ok bool) {
func ParseStickPosts(h *Handle) (r []models.Posts, ok bool) {
v := wpconfig.GetOption("sticky_posts") v := wpconfig.GetOption("sticky_posts")
if v == "" { if v == "" {
return return
@ -32,17 +32,17 @@ func (h *Handle) StickPosts() []models.Posts {
}) })
ok = true ok = true
return return
})
} }
func (h *Handle) StickMapPosts() map[uint64]models.Posts { var GetStickMapPosts = reload.BuildValFn("stickPostsMap", StickMapPosts)
return reload.GetAnyValBys("stickPostsMap", h, func(h *Handle) (map[uint64]models.Posts, bool) {
return slice.SimpleToMap(h.StickPosts(), func(v models.Posts) uint64 { func StickMapPosts(h *Handle) map[uint64]models.Posts {
return slice.SimpleToMap(GetStickPosts(h), func(v models.Posts) uint64 {
return v.Id return v.Id
}), true
}) })
} }
func (h *Handle) IsStick(id uint64) bool { func (h *Handle) IsStick(id uint64) bool {
return maps.IsExists(h.StickMapPosts(), id) _, ok := GetStickMapPosts(h)[id]
return ok
} }

View File

@ -10,6 +10,7 @@ import (
"github.com/fthvgb1/wp-go/cache/reload" "github.com/fthvgb1/wp-go/cache/reload"
"github.com/fthvgb1/wp-go/helper/maps" "github.com/fthvgb1/wp-go/helper/maps"
str "github.com/fthvgb1/wp-go/helper/strings" str "github.com/fthvgb1/wp-go/helper/strings"
"github.com/fthvgb1/wp-go/safety"
"github.com/gin-contrib/sessions" "github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"html/template" "html/template"
@ -19,10 +20,9 @@ import (
) )
type Handle struct { type Handle struct {
Index *IndexHandle
Detail *DetailHandle
C *gin.Context C *gin.Context
theme string theme string
isInited bool
Session sessions.Session Session sessions.Session
ginH gin.H ginH gin.H
password string password string
@ -30,19 +30,16 @@ type Handle struct {
Code int Code int
Stats string Stats string
templ string templ string
components map[string]map[string][]Components[string]
componentHook map[string][]func(Components[string]) (Components[string], bool)
themeMods wpconfig.ThemeMods themeMods wpconfig.ThemeMods
handlers map[string]map[string][]HandleCall
handleHook map[string][]func(HandleCall) (HandleCall, bool)
err error err error
abort bool abort bool
stopPipe bool stopPipe bool
componentsArgs map[string]any
componentFilterFn map[string][]func(*Handle, string, ...any) string
template *template.Template template *template.Template
} }
var handlerss = safety.NewMap[string, map[string][]HandleCall]()
var handleHooks = safety.NewMap[string, []func(HandleCall) (HandleCall, bool)]()
func (h *Handle) Theme() string { func (h *Handle) Theme() string {
return h.theme return h.theme
} }
@ -55,20 +52,20 @@ func (h *Handle) SetScene(scene string) {
h.scene = scene h.scene = scene
} }
func (h *Handle) Components() map[string]map[string][]Components[string] { func (h *Handle) Components() *safety.Map[string, map[string][]Components[string]] {
return h.components return handleComponents
} }
func (h *Handle) ComponentHook() map[string][]func(Components[string]) (Components[string], bool) { func (h *Handle) ComponentHook() *safety.Map[string, []func(Components[string]) (Components[string], bool)] {
return h.componentHook return handleComponentHook
} }
func (h *Handle) Handlers() map[string]map[string][]HandleCall { func (h *Handle) Handlers() *safety.Map[string, map[string][]HandleCall] {
return h.handlers return handlerss
} }
func (h *Handle) HandleHook() map[string][]func(HandleCall) (HandleCall, bool) { func (h *Handle) HandleHook() *safety.Map[string, []func(HandleCall) (HandleCall, bool)] {
return h.handleHook return handleHooks
} }
func (h *Handle) SetTemplate(template *template.Template) { func (h *Handle) SetTemplate(template *template.Template) {
@ -98,45 +95,48 @@ type HandleCall struct {
Name string Name string
} }
func InitHandle(fn func(*Handle), h *Handle) { func SetConfigHandle(a ...any) Handle {
var inited = false configFn := a[0].(func(*Handle))
hh := reload.GetAnyValBys("themeArgAndConfig", h, func(h *Handle) (Handle, bool) { hh := a[1].(*Handle)
h.components = make(map[string]map[string][]Components[string]) h := &Handle{}
h.componentsArgs = make(map[string]any) mut := reload.GetGlobeMutex()
h.componentFilterFn = make(map[string][]func(*Handle, string, ...any) string) mut.Lock()
h.handlers = make(map[string]map[string][]HandleCall) defer mut.Unlock()
h.handleHook = make(map[string][]func(HandleCall) (HandleCall, bool)) handleComponents.Flush()
componentsArgs.Flush()
handleComponentHook.Flush()
componentFilterFns.Flush()
handlerss.Flush()
handleHooks.Flush()
h.ginH = gin.H{} h.ginH = gin.H{}
fnMap.Flush() fnMap.Flush()
fnHook.Flush() fnHook.Flush()
fn(h) h.C = hh.C
h.theme = hh.theme
h.template = hh.template
configFn(h)
v := apply.UsePlugins() v := apply.UsePlugins()
pluginFn, ok := v.(func(*Handle)) pluginFn, ok := v.(func(*Handle))
if ok { if ok {
pluginFn(h) pluginFn(h)
} }
h.C.Set("inited", true) return *h
inited = true }
return *h, true
}) var GetInitHandleFn = reload.BuildValFnWithAnyParams("themeArgAndConfig", SetConfigHandle, 100.01)
type ConfigParm struct {
ConfigFn func(*Handle)
H *Handle
}
func InitHandle(configFn func(*Handle), h *Handle) {
hh := GetInitHandleFn(configFn, h)
h.ginH = maps.Copy(hh.ginH) h.ginH = maps.Copy(hh.ginH)
h.ginH["calPostClass"] = postClass(h) h.ginH["calPostClass"] = postClass(h)
h.ginH["calBodyClass"] = bodyClass(h) h.ginH["calBodyClass"] = bodyClass(h)
h.ginH["customLogo"] = customLogo(h) h.ginH["customLogo"] = customLogo(h)
if inited { h.isInited = true
return
}
h.components = hh.components
h.Index.postsPlugin = hh.Index.postsPlugin
h.Index.pageEle = hh.Index.pageEle
h.Detail.CommentRender = hh.Detail.CommentRender
h.Detail.CommentPageEle = hh.Detail.CommentPageEle
h.handlers = hh.handlers
h.handleHook = hh.handleHook
h.componentHook = hh.componentHook
h.componentsArgs = hh.componentsArgs
h.componentFilterFn = hh.componentFilterFn
h.C.Set("inited", true)
} }
func (h *Handle) Abort() { func (h *Handle) Abort() {

View File

@ -181,10 +181,10 @@ func NewPaginationCache[K comparable, V any](m *cache.MapCache[string, helper.Pa
} }
} }
if ma == nil { if ma == nil {
ma = reload.FnVal(str.Join("paginationCache-", name, "-maxNum"), maxNum, nil) ma = reload.BuildFnVal(str.Join("paginationCache-", name, "-maxNum"), maxNum, nil)
} }
if fet == nil { if fet == nil {
fet = reload.FnVal(str.Join("paginationCache-", name, "-fetchNum"), fetchNum, nil) fet = reload.BuildFnVal(str.Join("paginationCache-", name, "-fetchNum"), fetchNum, nil)
} }
p := cache.NewPagination(m, ma, dbFn, localFn, dbKeyFn, localKeyFn, fet, name) p := cache.NewPagination(m, ma, dbFn, localFn, dbKeyFn, localKeyFn, fet, name)
mapCache.Store(name, p) mapCache.Store(name, p)
@ -215,7 +215,7 @@ func buildLockFn[K comparable](args ...any) cache.LockFn[K] {
} }
loFn = helper.ParseArgs(loFn, args...) loFn = helper.ParseArgs(loFn, args...)
if name != "" { if name != "" {
loFn = reload.FnVal(str.Join("cachesLocksNum-", name), num, loFn) loFn = reload.BuildFnVal(str.Join("cachesLocksNum-", name), num, loFn)
} }
if lockFn == nil { if lockFn == nil {
looo := helper.ParseArgs(cache.Lockss[K](nil), args...) looo := helper.ParseArgs(cache.Lockss[K](nil), args...)
@ -247,13 +247,13 @@ func SetExpireTime(c cache.SetTime, name string, expireTime time.Duration, expir
if name == "" { if name == "" {
return return
} }
fn := reload.FnVal(str.Join("cacheManger-", name, "-expiredTime"), expireTime, expireTimeFn) fn := reload.BuildFnVal(str.Join("cacheManger-", name, "-expiredTime"), expireTime, expireTimeFn)
c.SetExpiredTime(fn) c.SetExpiredTime(fn)
} }
func ChangeExpireTime(t time.Duration, coverConf bool, name ...string) { func ChangeExpireTime(t time.Duration, coverConf bool, name ...string) {
for _, s := range name { for _, s := range name {
reload.ChangeFnVal(s, t, coverConf) reload.SetFnVal(s, t, coverConf)
} }
} }

2
cache/map.go vendored
View File

@ -56,7 +56,7 @@ type IncreaseUpdate[K comparable, V any] struct {
} }
func NewIncreaseUpdate[K comparable, V any](name string, fn IncreaseFn[K, V], cycleTime time.Duration, tFn func() time.Duration) *IncreaseUpdate[K, V] { func NewIncreaseUpdate[K comparable, V any](name string, fn IncreaseFn[K, V], cycleTime time.Duration, tFn func() time.Duration) *IncreaseUpdate[K, V] {
tFn = reload.FnVal(name, cycleTime, tFn) tFn = reload.BuildFnVal(name, cycleTime, tFn)
return &IncreaseUpdate[K, V]{CycleTime: tFn, Fn: fn} return &IncreaseUpdate[K, V]{CycleTime: tFn, Fn: fn}
} }

4
cache/map_test.go vendored
View File

@ -23,7 +23,7 @@ func init() {
ct = context.Background() ct = context.Background()
batchFn = func(ctx context.Context, arr []string, a ...any) (map[string]string, error) { batchFn = func(ctx context.Context, arr []string, a ...any) (map[string]string, error) {
fmt.Println(a) fmt.Println(a)
return slice.FilterAndToMap(arr, func(t string) (string, string, bool) { return slice.FilterAndToMap(arr, func(t string, _ int) (string, string, bool) {
return t, strings.Repeat(t, 2), true return t, strings.Repeat(t, 2), true
}), nil }), nil
} }
@ -69,7 +69,7 @@ func TestMapCache_Flush(t *testing.T) {
} }
ca := *NewMapCache[string, string](NewMemoryMapCache[string, string](func() time.Duration { ca := *NewMapCache[string, string](NewMemoryMapCache[string, string](func() time.Duration {
return time.Second return time.Second
}), fn, nil) }), fn, nil, nil, nil)
_, _ = ca.GetCache(ct, "aa", time.Second, ct, "aa") _, _ = ca.GetCache(ct, "aa", time.Second, ct, "aa")
tests := []testCase[string, string]{ tests := []testCase[string, string]{
{ {

393
cache/reload/reload.go vendored
View File

@ -14,32 +14,47 @@ type queue struct {
name string name string
} }
var calls = safety.NewSlice(make([]queue, 0)) var mut = &sync.Mutex{}
var callsM = safety.NewMap[string, func()]()
var anyMap = safety.NewMap[string, any]() func GetGlobeMutex() *sync.Mutex {
return mut
}
type safetyVar[T, A any] struct { var waitReloadCalls = safety.NewSlice(make([]queue, 0))
Val *safety.Var[val[T]] var callMap = safety.NewMap[string, func()]()
mutex sync.Mutex
var setFnVal = safety.NewMap[string, any]()
type SafetyVar[T, A any] struct {
Val *safety.Var[Val[T]]
Mutex sync.Mutex
} }
type val[T any] struct { type Val[T any] struct {
v T V T
ok bool Ok bool
counter number.Counter[int]
} }
type safetyMap[K comparable, V, A any] struct { type SafetyMap[K comparable, V, A any] struct {
val *safety.Map[K, V] Val *safety.Map[K, V]
mutex sync.Mutex Mutex sync.Mutex
} }
var safetyMaps = safety.NewMap[string, any]() var safetyMaps = safety.NewMap[string, any]()
var safetyMapLock = sync.Mutex{} var safetyMapLock = sync.Mutex{}
var flushMapFn = safety.NewMap[string, func(any)]() var deleteMapFn = safety.NewMap[string, func(any)]()
func FlushMapVal[T any](namespace string, key ...T) { // GetValMap can get stored map value with namespace which called BuildSafetyMap, BuildMapFnWithConfirm, BuildMapFn, BuildMapFnWithAnyParams
fn, ok := flushMapFn.Load(namespace) func GetValMap[K comparable, V any](namespace string) (*safety.Map[K, V], bool) {
m, ok := safetyMaps.Load(namespace)
if !ok {
return nil, false
}
v, ok := m.(*safety.Map[K, V])
return v, ok
}
func DeleteMapVal[T any](namespace string, key ...T) {
fn, ok := deleteMapFn.Load(namespace)
if !ok || len(key) < 1 { if !ok || len(key) < 1 {
return return
} }
@ -48,7 +63,7 @@ func FlushMapVal[T any](namespace string, key ...T) {
func FlushAnyVal(namespaces ...string) { func FlushAnyVal(namespaces ...string) {
for _, namespace := range namespaces { for _, namespace := range namespaces {
fn, ok := callsM.Load(namespace) fn, ok := callMap.Load(namespace)
if !ok { if !ok {
continue continue
} }
@ -56,93 +71,142 @@ func FlushAnyVal(namespaces ...string) {
} }
} }
func GetAnyMapFnBys[K comparable, V, A any](namespace string, fn func(A) V) func(key K, args A) V { // BuildMapFnWithConfirm same as BuildMapFn
m := safetyMapFn[K, V, A](namespace) func BuildMapFnWithConfirm[K comparable, V, A any](namespace string, fn func(A) (V, bool), a ...any) func(key K, args A) V {
m := BuildSafetyMap[K, V, A](namespace, a...)
return func(key K, a A) V { return func(key K, a A) V {
v, ok := m.val.Load(key) v, ok := m.Val.Load(key)
if ok { if ok {
return v return v
} }
m.mutex.Lock() m.Mutex.Lock()
defer m.mutex.Unlock() defer m.Mutex.Unlock()
v, ok = m.val.Load(key) v, ok = m.Val.Load(key)
if ok {
return v
}
v = fn(a)
m.val.Store(key, v)
return v
}
}
func safetyMapFn[K comparable, V, A any](namespace string, args ...any) *safetyMap[K, V, A] {
vv, ok := safetyMaps.Load(namespace)
var m *safetyMap[K, V, A]
if ok {
m = vv.(*safetyMap[K, V, A])
} else {
safetyMapLock.Lock()
defer safetyMapLock.Unlock()
vv, ok = safetyMaps.Load(namespace)
if ok {
m = vv.(*safetyMap[K, V, A])
} else {
m = &safetyMap[K, V, A]{safety.NewMap[K, V](), sync.Mutex{}}
ord, _ := parseArgs(args...)
flushMapFn.Store(namespace, func(a any) {
k, ok := a.([]K)
if !ok && len(k) > 0 {
return
}
for _, key := range k {
m.val.Delete(key)
}
})
Push(func() {
m.val.Flush()
}, ord, namespace)
safetyMaps.Store(namespace, m)
}
}
return m
}
func GetAnyValMapBy[K comparable, V, A any](namespace string, key K, a A, fn func(A) (V, bool), args ...any) V {
m := safetyMapFn[K, V, A](namespace, args...)
v, ok := m.val.Load(key)
if ok {
return v
}
m.mutex.Lock()
defer m.mutex.Unlock()
v, ok = m.val.Load(key)
if ok { if ok {
return v return v
} }
v, ok = fn(a) v, ok = fn(a)
if ok { if ok {
m.val.Store(key, v) m.Val.Store(key, v)
}
return v
}
}
// BuildMapFn build given fn with a new fn which returned value can be saved and flushed when called Reload or FlushAnyVal
// with namespace
//
// if give a float then can be reloaded early or lately, more bigger more earlier
//
// if give a bool false will not flushed when called Reload, then can called GetValMap to flush manually
func BuildMapFn[K comparable, V, A any](namespace string, fn func(A) V, a ...any) func(key K, args A) V {
m := BuildSafetyMap[K, V, A](namespace, a...)
return func(key K, a A) V {
v, ok := m.Val.Load(key)
if ok {
return v
}
m.Mutex.Lock()
defer m.Mutex.Unlock()
v, ok = m.Val.Load(key)
if ok {
return v
}
v = fn(a)
m.Val.Store(key, v)
return v
}
}
// BuildMapFnWithAnyParams same as BuildMapFn use multiple params
func BuildMapFnWithAnyParams[K comparable, V any](namespace string, fn func(...any) V, a ...any) func(key K, a ...any) V {
m := BuildSafetyMap[K, V, any](namespace, a...)
return func(key K, a ...any) V {
v, ok := m.Val.Load(key)
if ok {
return v
}
m.Mutex.Lock()
defer m.Mutex.Unlock()
v, ok = m.Val.Load(key)
if ok {
return v
}
v = fn(a)
m.Val.Store(key, v)
return v
}
}
func BuildSafetyMap[K comparable, V, A any](namespace string, args ...any) *SafetyMap[K, V, A] {
vv, ok := safetyMaps.Load(namespace)
var m *SafetyMap[K, V, A]
if ok {
m = vv.(*SafetyMap[K, V, A])
return m
}
safetyMapLock.Lock()
defer safetyMapLock.Unlock()
vv, ok = safetyMaps.Load(namespace)
if ok {
m = vv.(*SafetyMap[K, V, A])
return m
}
m = &SafetyMap[K, V, A]{safety.NewMap[K, V](), sync.Mutex{}}
ord, _ := parseArgs(args...)
autoFlush := helper.ParseArgs(true, args...)
deleteMapFn.Store(namespace, func(a any) {
k, ok := a.([]K)
if !ok && len(k) > 0 {
return
}
for _, key := range k {
m.Val.Delete(key)
}
})
if autoFlush {
Push(func() {
m.Val.Flush()
}, ord, namespace)
}
safetyMaps.Store(namespace, m)
return m
}
func GetAnyValMapBy[K comparable, V, A any](namespace string, key K, a A, fn func(A) (V, bool), args ...any) V {
m := BuildSafetyMap[K, V, A](namespace, args...)
v, ok := m.Val.Load(key)
if ok {
return v
}
m.Mutex.Lock()
defer m.Mutex.Unlock()
v, ok = m.Val.Load(key)
if ok {
return v
}
v, ok = fn(a)
if ok {
m.Val.Store(key, v)
} }
return v return v
} }
func anyVal[T, A any](namespace string, counter bool, args ...any) *safetyVar[T, A] { func BuildAnyVal[T, A any](namespace string, counter bool, args ...any) *SafetyVar[T, A] {
var vv *safetyVar[T, A] var vv *SafetyVar[T, A]
vvv, ok := safetyMaps.Load(namespace) vvv, ok := safetyMaps.Load(namespace)
if ok { if ok {
vv = vvv.(*safetyVar[T, A]) vv = vvv.(*SafetyVar[T, A])
} else { } else {
safetyMapLock.Lock() safetyMapLock.Lock()
defer safetyMapLock.Unlock() defer safetyMapLock.Unlock()
vvv, ok = safetyMaps.Load(namespace) vvv, ok = safetyMaps.Load(namespace)
if ok { if ok {
vv = vvv.(*safetyVar[T, A]) vv = vvv.(*SafetyVar[T, A])
} else { } else {
v := val[T]{} v := Val[T]{}
if counter { vv = &SafetyVar[T, A]{safety.NewVar(v), sync.Mutex{}}
v.counter = number.Counters[int]()
}
vv = &safetyVar[T, A]{safety.NewVar(v), sync.Mutex{}}
ord, _ := parseArgs(args...) ord, _ := parseArgs(args...)
Push(func() { Push(func() {
vv.Val.Flush() vv.Val.Flush()
@ -153,53 +217,117 @@ func anyVal[T, A any](namespace string, counter bool, args ...any) *safetyVar[T,
return vv return vv
} }
func GetAnyValBy[T, A any](namespace string, a A, fn func(A) (T, bool), args ...any) T { func GetAnyValBys[T, A any](namespace string, a A, fn func(A) (T, bool), args ...any) T {
var vv = anyVal[T, A](namespace, true, args...) var vv = BuildAnyVal[T, A](namespace, false, args...)
var ok bool
v := vv.Val.Load() v := vv.Val.Load()
if v.ok { if v.Ok {
return v.v return v.V
} }
vv.mutex.Lock() vv.Mutex.Lock()
defer vv.mutex.Unlock() defer vv.Mutex.Unlock()
v = vv.Val.Load() v = vv.Val.Load()
if v.ok { if v.Ok {
return v.v return v.V
} }
v.v, ok = fn(a) v.V, v.Ok = fn(a)
if v.counter == nil {
v.counter = number.Counters[int]()
}
times := v.counter()
tryTimes := helper.ParseArgs(1, args...)
if ok || times >= tryTimes {
v.ok = true
vv.Val.Store(v) vv.Val.Store(v)
} return v.V
return v.v
} }
func GetAnyValBys[T, A any](namespace string, a A, fn func(A) (T, bool), args ...any) T { // BuildValFnWithConfirm same as BuildValFn
var vv = anyVal[T, A](namespace, false, args...) //
// if give a int and value bigger than 1 will be a times which built fn called return false
func BuildValFnWithConfirm[T, A any](namespace string, fn func(A) (T, bool), args ...any) func(A) T {
var vv = BuildAnyVal[T, A](namespace, false, args...)
tryTimes := helper.ParseArgs(1, args...)
var counter func() int
if tryTimes > 1 {
counter = number.Counters[int]()
}
return func(a A) T {
v := vv.Val.Load() v := vv.Val.Load()
if v.ok { if v.Ok {
return v.v return v.V
} }
vv.mutex.Lock() vv.Mutex.Lock()
defer vv.mutex.Unlock() defer vv.Mutex.Unlock()
v = vv.Val.Load() v = vv.Val.Load()
if v.ok { if v.Ok {
return v.v return v.V
} }
v.v, v.ok = fn(a) v.V, v.Ok = fn(a)
if v.Ok {
vv.Val.Store(v) vv.Val.Store(v)
return v.v return v.V
}
if counter == nil {
return v.V
}
times := counter()
if times >= tryTimes {
v.Ok = true
vv.Val.Store(v)
}
return v.V
}
}
// BuildValFn build given fn a new fn which return value can be saved and flushed when called Reload or FlushAnyVal
// with namespace.
//
// note: namespace should be not same as BuildMapFn and related fn, they stored same safety.Map[string,any].
//
// if give a float then can be reloaded early or lately, more bigger more earlier
//
// if give a bool false will not flushed when called Reload, then can called GetValMap to flush manually
func BuildValFn[T, A any](namespace string, fn func(A) T, args ...any) func(A) T {
var vv = BuildAnyVal[T, A](namespace, false, args...)
return func(a A) T {
v := vv.Val.Load()
if v.Ok {
return v.V
}
vv.Mutex.Lock()
defer vv.Mutex.Unlock()
v = vv.Val.Load()
if v.Ok {
return v.V
}
v.V = fn(a)
v.Ok = true
vv.Val.Store(v)
return v.V
}
}
// BuildValFnWithAnyParams same as BuildValFn use multiple params
func BuildValFnWithAnyParams[T any](namespace string, fn func(...any) T, args ...any) func(...any) T {
var vv = BuildAnyVal[T, any](namespace, false, args...)
return func(a ...any) T {
v := vv.Val.Load()
if v.Ok {
return v.V
}
vv.Mutex.Lock()
defer vv.Mutex.Unlock()
v = vv.Val.Load()
if v.Ok {
return v.V
}
v.V = fn(a...)
v.Ok = true
vv.Val.Store(v)
return v.V
}
} }
// Vars get default value and whenever reloaded assign default value // Vars get default value and whenever reloaded assign default value
// //
// args same as Push // args same as Push
//
// if give a name, then can be flushed by calls FlushAnyVal // if give a name, then can be flushed by calls FlushAnyVal
//
// if give a float then can be reloaded early or lately, more bigger more earlier
func Vars[T any](defaults T, args ...any) *safety.Var[T] { func Vars[T any](defaults T, args ...any) *safety.Var[T] {
ss := safety.NewVar(defaults) ss := safety.NewVar(defaults)
ord, name := parseArgs(args...) ord, name := parseArgs(args...)
@ -261,25 +389,29 @@ func SafeMap[K comparable, T any](args ...any) *safety.Map[K, T] {
return m return m
} }
// Push the func that will be call whenever Reload called // Push the func that will be called whenever Reload called
// //
// if give a name, then can be flushed by calls FlushAnyVal // if give a name, then can be called by called FlushAnyVal
//
// if give a float then can be called early or lately when called Reload, more bigger more earlier
func Push(fn func(), a ...any) { func Push(fn func(), a ...any) {
ord, name := parseArgs(a...) ord, name := parseArgs(a...)
calls.Append(queue{fn, ord, name}) waitReloadCalls.Append(queue{fn, ord, name})
if name != "" { if name != "" {
callsM.Store(name, fn) callMap.Store(name, fn)
} }
} }
func Reload() { func Reload() {
callsM.Flush() mut.Lock()
flushMapFn.Flush() defer mut.Unlock()
callll := calls.Load() callMap.Flush()
slice.SimpleSort(callll, slice.DESC, func(t queue) float64 { deleteMapFn.Flush()
reloadCalls := waitReloadCalls.Load()
slice.SimpleSort(reloadCalls, slice.DESC, func(t queue) float64 {
return t.order return t.order
}) })
for _, call := range callll { for _, call := range reloadCalls {
call.fn() call.fn()
} }
return return
@ -288,10 +420,11 @@ func Reload() {
type Any[T any] struct { type Any[T any] struct {
fn func() T fn func() T
v *safety.Var[T] v *safety.Var[T]
isUseManger *safety.Var[bool] isManual *safety.Var[bool]
} }
func FnVal[T any](name string, t T, fn func() T) func() T { // BuildFnVal build a new fn which can be set value by SetFnVal with name or set default value by given fn when called Reload
func BuildFnVal[T any](name string, t T, fn func() T) func() T {
if fn == nil { if fn == nil {
fn = func() T { fn = func() T {
return t return t
@ -303,21 +436,21 @@ func FnVal[T any](name string, t T, fn func() T) func() T {
e := Any[T]{ e := Any[T]{
fn: fn, fn: fn,
v: p, v: p,
isUseManger: safety.NewVar(false), isManual: safety.NewVar(false),
} }
Push(func() { Push(func() {
if !e.isUseManger.Load() { if !e.isManual.Load() {
e.v.Store(fn()) e.v.Store(fn())
} }
}) })
anyMap.Store(name, e) setFnVal.Store(name, e)
return func() T { return func() T {
return e.v.Load() return e.v.Load()
} }
} }
func ChangeFnVal[T any](name string, val T, coverConf bool) { func SetFnVal[T any](name string, val T, onlyManual bool) {
v, ok := anyMap.Load(name) v, ok := setFnVal.Load(name)
if !ok { if !ok {
return return
} }
@ -325,8 +458,8 @@ func ChangeFnVal[T any](name string, val T, coverConf bool) {
if !ok { if !ok {
return return
} }
if coverConf && !vv.isUseManger.Load() { if onlyManual && !vv.isManual.Load() {
vv.isUseManger.Store(true) vv.isManual.Store(true)
} }
vv.v.Store(val) vv.v.Store(val)
} }

View File

@ -13,7 +13,7 @@ func TestFlushMapVal(t *testing.T) {
return 33, true return 33, true
}) })
fmt.Println(v) fmt.Println(v)
FlushMapVal("key", 2) DeleteMapVal("key", 2)
v = GetAnyValMapBy("key", 2, struct{}{}, func(a struct{}) (int, bool) { v = GetAnyValMapBy("key", 2, struct{}{}, func(a struct{}) (int, bool) {
fmt.Println("xxxxx") fmt.Println("xxxxx")
@ -32,15 +32,15 @@ func TestFlushMapVal(t *testing.T) {
func TestGetAnyMapFnBys(t *testing.T) { func TestGetAnyMapFnBys(t *testing.T) {
var i int var i int
t.Run("t1", func(t *testing.T) { t.Run("t1", func(t *testing.T) {
v := GetAnyMapFnBys[int]("name", func(a int) int { v := BuildMapFnWithConfirm[int]("name", func(a int) (int, bool) {
i++ i++
return a + 1 return a + 1, true
}) })
vv := v(1, 2) vv := v(1, 2)
vvv := v(2, 3) vvv := v(2, 3)
fmt.Println(vv, vvv) fmt.Println(vv, vvv)
v(1, 2) v(1, 2)
FlushMapVal("name", 2) DeleteMapVal("name", 2)
v(2, 3) v(2, 3)
fmt.Println(i) fmt.Println(i)
}) })

View File

@ -192,8 +192,8 @@ func WithDefaultVal[K comparable, V any](m map[K]V, k K, defaults V) V {
return defaults return defaults
} }
func AnyAnyMap[K comparable, V any](m map[any]any, fn func(k, v any) (K, V, bool)) map[K]V { func AnyAnyMapTo[K comparable, V any](m map[any]any, fn func(k, v any) (K, V, bool)) map[K]V {
mm := make(map[K]V, 0) mm := make(map[K]V)
for k, v := range m { for k, v := range m {
key, val, ok := fn(k, v) key, val, ok := fn(k, v)
if ok { if ok {

View File

@ -172,10 +172,10 @@ func Slice[T any](arr []T, offset, length int) (r []T) {
return return
} }
func FilterAndToMap[K comparable, V, T any](arr []T, fn func(T) (K, V, bool)) map[K]V { func FilterAndToMap[K comparable, V, T any](arr []T, fn func(T, int) (K, V, bool)) map[K]V {
r := make(map[K]V) r := make(map[K]V)
for _, t := range arr { for i, t := range arr {
k, v, ok := fn(t) k, v, ok := fn(t, i)
if ok { if ok {
r[k] = v r[k] = v
} }