optimize code, fix bug and add some comments
This commit is contained in:
parent
8bdc53d175
commit
5e18c9babd
|
@ -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)
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
return config.GetConfig().ShowQuerySql
|
showQuerySql = reload.BuildFnVal("showQuerySql", false, func() bool {
|
||||||
})
|
return config.GetConfig().ShowQuerySql
|
||||||
|
})
|
||||||
|
}
|
||||||
return safeDb, err
|
return safeDb, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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", "")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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")
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
|
|
||||||
|
var getComponentFn = reload.BuildMapFn[string]("scene-components", getComponent)
|
||||||
|
var hookComponentFn = reload.BuildMapFn[string]("calComponents", hookComponent)
|
||||||
|
|
||||||
|
type componentParam struct {
|
||||||
|
components []Components[string]
|
||||||
|
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
|
||||||
|
})
|
||||||
|
mut.Unlock()
|
||||||
|
r := slice.FilterAndMap(p.components, func(component Components[string]) (Components[string], bool) {
|
||||||
|
hooks, ok := allHooks[p.k]
|
||||||
|
if !ok {
|
||||||
|
return component, true
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
func CalComponents(h *Handle) {
|
||||||
componentss := reload.GetAnyValMapBy("scene-components", str.Join("allScene-", h.scene), h, func(h *Handle) (map[string][]Components[string], bool) {
|
allComponents := getComponentFn(str.Join("allScene-", h.scene), h)
|
||||||
return maps.MergeBy(func(k string, v1, v2 []Components[string]) ([]Components[string], bool) {
|
for k, components := range allComponents {
|
||||||
vv := append(v1, v2...)
|
|
||||||
return vv, vv != nil
|
|
||||||
}, nil, h.components[h.scene], h.components[constraints.AllScene]), true
|
|
||||||
})
|
|
||||||
for k, components := range componentss {
|
|
||||||
key := str.Join("calComponents-", h.scene, "-", k)
|
key := str.Join("calComponents-", h.scene, "-", k)
|
||||||
ss := reload.GetAnyValMapBy("calComponents", key, h, func(h *Handle) ([]Components[string], bool) {
|
hookedComponents := hookComponentFn(key, componentParam{components, k})
|
||||||
r := slice.FilterAndMap(components, func(t Components[string]) (Components[string], bool) {
|
var s = make([]string, 0, len(hookedComponents))
|
||||||
fns, ok := h.componentHook[k]
|
for _, component := range hookedComponents {
|
||||||
if !ok {
|
|
||||||
return t, true
|
|
||||||
}
|
|
||||||
for _, fn := range fns {
|
|
||||||
c, ok := fn(t)
|
|
||||||
if !ok {
|
|
||||||
return c, false
|
|
||||||
}
|
|
||||||
t = c
|
|
||||||
}
|
|
||||||
return t, true
|
|
||||||
})
|
|
||||||
slice.SimpleSort(r, slice.DESC, func(t Components[string]) float64 {
|
|
||||||
return t.Order
|
|
||||||
})
|
|
||||||
return r, true
|
|
||||||
})
|
|
||||||
var s = make([]string, 0, len(ss))
|
|
||||||
for _, component := range ss {
|
|
||||||
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...)
|
||||||
|
|
|
@ -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,51 +68,64 @@ 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, " ")
|
||||||
|
}
|
||||||
|
|
||||||
|
var GetCategoryAttr = reload.BuildValFn("block-category-attr", parseAttr)
|
||||||
|
|
||||||
|
var GetCategoryConf = reload.BuildValFnWithConfirm("block-category-conf", categoryConfFn, 5)
|
||||||
|
|
||||||
|
func categoryConfFn(blockParser ParserBlock) (map[any]any, bool) {
|
||||||
|
var con any
|
||||||
|
err := json.Unmarshal([]byte(blockParser.Attrs), &con)
|
||||||
|
if err != nil {
|
||||||
|
logs.Error(err, "解析category attr错误", blockParser.Attrs)
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
var conf map[any]any
|
||||||
|
switch con.(type) {
|
||||||
|
case map[any]any:
|
||||||
|
conf = con.(map[any]any)
|
||||||
|
case map[string]any:
|
||||||
|
conf = maps.StrAnyToAnyAny(con.(map[string]any))
|
||||||
|
}
|
||||||
|
conf = maps.FilterZeroMerge(categoryConf(), conf)
|
||||||
|
|
||||||
|
if maps.GetAnyAnyValWithDefaults(conf, false, "showPostCounts") {
|
||||||
|
conf["count"] = int64(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if maps.GetAnyAnyValWithDefaults(conf, false, "displayAsDropdown") {
|
||||||
|
conf["dropdown"] = int64(1)
|
||||||
|
}
|
||||||
|
if maps.GetAnyAnyValWithDefaults(conf, false, "showHierarchy") {
|
||||||
|
conf["hierarchical"] = int64(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
class := maps.GetAnyAnyValWithDefaults(conf, "", "className")
|
||||||
|
classes := strings.Split(class, " ")
|
||||||
|
classes = append(classes, "wp-block-categories")
|
||||||
|
if conf["dropdown"].(int64) == 1 {
|
||||||
|
classes = append(classes, "wp-block-categories-dropdown")
|
||||||
|
conf["className"] = strings.Join(classes, " ")
|
||||||
|
} else {
|
||||||
|
classes = append(classes, "wp-block-categories-list")
|
||||||
|
conf["className"] = strings.Join(classes, " ")
|
||||||
|
}
|
||||||
|
return conf, true
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
func Category(h *wp.Handle, id string, blockParser ParserBlock) (func() string, error) {
|
||||||
counter := number.Counters[int]()
|
counter := number.Counters[int]()
|
||||||
var err error
|
var err error
|
||||||
conf := reload.GetAnyValBy("block-category-conf", h, func(h *wp.Handle) (map[any]any, bool) {
|
conf := GetCategoryConf(blockParser)
|
||||||
var con any
|
|
||||||
err = json.Unmarshal([]byte(blockParser.Attrs), &con)
|
|
||||||
if err != nil {
|
|
||||||
logs.Error(err, "解析category attr错误", blockParser.Attrs)
|
|
||||||
return nil, false
|
|
||||||
}
|
|
||||||
var conf map[any]any
|
|
||||||
switch con.(type) {
|
|
||||||
case map[any]any:
|
|
||||||
conf = con.(map[any]any)
|
|
||||||
case map[string]any:
|
|
||||||
conf = maps.StrAnyToAnyAny(con.(map[string]any))
|
|
||||||
}
|
|
||||||
conf = maps.FilterZeroMerge(categoryConf(), conf)
|
|
||||||
|
|
||||||
if maps.GetAnyAnyValWithDefaults(conf, false, "showPostCounts") {
|
|
||||||
conf["count"] = int64(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
if maps.GetAnyAnyValWithDefaults(conf, false, "displayAsDropdown") {
|
|
||||||
conf["dropdown"] = int64(1)
|
|
||||||
}
|
|
||||||
if maps.GetAnyAnyValWithDefaults(conf, false, "showHierarchy") {
|
|
||||||
conf["hierarchical"] = int64(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
class := maps.GetAnyAnyValWithDefaults(conf, "", "className")
|
|
||||||
classes := strings.Split(class, " ")
|
|
||||||
classes = append(classes, "wp-block-categories")
|
|
||||||
if conf["dropdown"].(int64) == 1 {
|
|
||||||
classes = append(classes, "wp-block-categories-dropdown")
|
|
||||||
conf["className"] = strings.Join(classes, " ")
|
|
||||||
} else {
|
|
||||||
classes = append(classes, "wp-block-categories-list")
|
|
||||||
conf["className"] = strings.Join(classes, " ")
|
|
||||||
}
|
|
||||||
return conf, true
|
|
||||||
}, 5)
|
|
||||||
|
|
||||||
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()
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,21 +40,29 @@ var archivesConfig = map[any]any{
|
||||||
"title": "归档",
|
"title": "归档",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var GetArchiveConf = BuildconfigFn(archivesConfig, "widget_archives", int64(2))
|
||||||
|
var GetArchiveArgs = reload.BuildValFnWithAnyParams("", archiveArgsFn)
|
||||||
|
|
||||||
|
func archiveArgsFn(a ...any) map[string]string {
|
||||||
|
h := a[0].(*wp.Handle)
|
||||||
|
conf := a[1].(map[any]any)
|
||||||
|
id := a[2].(string)
|
||||||
|
archiveArgs := archiveArgs()
|
||||||
|
commonArgs := wp.GetComponentsArgs(widgets.Widget, CommonArgs())
|
||||||
|
args := wp.GetComponentsArgs(widgets.Archive, archiveArgs)
|
||||||
|
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["{$title}"] = str.Join(args["{$before_title}"], conf["title"].(string), args["{$after_title}"])
|
||||||
|
if conf["dropdown"].(int64) == 0 && slice.IsContained(h.CommonThemeMods().ThemeSupport.HTML5, "navigation-widgets") {
|
||||||
|
args["{$nav}"] = fmt.Sprintf(`<nav aria-label="%s">`, conf["title"].(string))
|
||||||
|
args["{$navCloser}"] = "</nav>"
|
||||||
|
}
|
||||||
|
return args
|
||||||
|
}
|
||||||
|
|
||||||
func Archive(h *wp.Handle, id string) string {
|
func Archive(h *wp.Handle, id string) string {
|
||||||
conf := configs(archivesConfig, "widget_archives", int64(2))
|
conf := GetArchiveConf()
|
||||||
args := reload.GetAnyValBys("widget-archive-args", h, func(h *wp.Handle) (map[string]string, bool) {
|
args := GetArchiveArgs(h, conf, id)
|
||||||
archiveArgs := archiveArgs()
|
|
||||||
commonArgs := wp.GetComponentsArgs(h, widgets.Widget, CommonArgs())
|
|
||||||
args := wp.GetComponentsArgs(h, widgets.Archive, archiveArgs)
|
|
||||||
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["{$title}"] = str.Join(args["{$before_title}"], conf["title"].(string), args["{$after_title}"])
|
|
||||||
if conf["dropdown"].(int64) == 0 && slice.IsContained(h.CommonThemeMods().ThemeSupport.HTML5, "navigation-widgets") {
|
|
||||||
args["{$nav}"] = fmt.Sprintf(`<nav aria-label="%s">`, conf["title"].(string))
|
|
||||||
args["{$navCloser}"] = "</nav>"
|
|
||||||
}
|
|
||||||
return args, true
|
|
||||||
})
|
|
||||||
|
|
||||||
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 := ""
|
||||||
|
|
|
@ -44,22 +44,29 @@ func categoryArgs() map[string]string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var GetCategoryConf = BuildconfigFn(categoryConfig, "widget_categories", int64(2))
|
||||||
|
|
||||||
|
var GetCategoryArgs = reload.BuildValFnWithAnyParams("widget-category-args", categoryArgsFn)
|
||||||
|
|
||||||
|
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["{$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}"])
|
||||||
|
if conf["dropdown"].(int64) == 0 && slice.IsContained(h.CommonThemeMods().ThemeSupport.HTML5, "navigation-widgets") {
|
||||||
|
args["{$nav}"] = fmt.Sprintf(`<nav aria-label="%s">`, args["{title}"])
|
||||||
|
args["{$navCloser}"] = "</nav>"
|
||||||
|
}
|
||||||
|
return args
|
||||||
|
}
|
||||||
|
|
||||||
func Category(h *wp.Handle, id string) string {
|
func Category(h *wp.Handle, id string) string {
|
||||||
conf := configs(categoryConfig, "widget_categories", int64(2))
|
conf := GetCategoryConf()
|
||||||
|
args := GetCategoryArgs(h, conf, id)
|
||||||
args := reload.GetAnyValBys("widget-category-args", h, func(h *wp.Handle) (map[string]string, bool) {
|
|
||||||
commonArgs := wp.GetComponentsArgs(h, widgets.Widget, map[string]string{})
|
|
||||||
args := wp.GetComponentsArgs(h, widgets.Categories, categoryArgs())
|
|
||||||
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["{$title}"] = str.Join(args["{$before_title}"], conf["title"].(string), args["{$after_title}"])
|
|
||||||
if conf["dropdown"].(int64) == 0 && slice.IsContained(h.CommonThemeMods().ThemeSupport.HTML5, "navigation-widgets") {
|
|
||||||
args["{$nav}"] = fmt.Sprintf(`<nav aria-label="%s">`, args["{title}"])
|
|
||||||
args["{$navCloser}"] = "</nav>"
|
|
||||||
}
|
|
||||||
return args, true
|
|
||||||
})
|
|
||||||
|
|
||||||
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
|
||||||
|
|
|
@ -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...))
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,34 +21,39 @@ 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{})
|
|
||||||
metaArgs := metaArgs()
|
|
||||||
args := wp.GetComponentsArgs(h, widgets.Meta, metaArgs)
|
|
||||||
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["{$title}"] = wpconfig.GetPHPArrayVal("widget_meta", "其它操作", int64(2), "title")
|
|
||||||
if args["{$title}"] == "" {
|
|
||||||
args["{$title}"] = "其他操作"
|
|
||||||
}
|
|
||||||
if args["{$title}"] != "" {
|
|
||||||
args["{$h2title}"] = str.Join(args["{$before_title}"], args["{$title}"], args["{$after_title}"])
|
|
||||||
}
|
|
||||||
if slice.IsContained(h.CommonThemeMods().ThemeSupport.HTML5, "navigation-widgets") {
|
|
||||||
args["{$nav}"] = fmt.Sprintf(`<nav aria-label="%s">`, args["{$title}"])
|
|
||||||
args["{$navCloser}"] = "</nav>"
|
|
||||||
}
|
|
||||||
return args, true
|
|
||||||
})
|
|
||||||
|
|
||||||
|
func ParseMetaArgs(a ...any) map[string]string {
|
||||||
|
h := a[0].(*wp.Handle)
|
||||||
|
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["{$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")
|
||||||
|
if args["{$title}"] == "" {
|
||||||
|
args["{$title}"] = "其他操作"
|
||||||
|
}
|
||||||
|
if args["{$title}"] != "" {
|
||||||
|
args["{$h2title}"] = str.Join(args["{$before_title}"], args["{$title}"], args["{$after_title}"])
|
||||||
|
}
|
||||||
|
if slice.IsContained(h.CommonThemeMods().ThemeSupport.HTML5, "navigation-widgets") {
|
||||||
|
args["{$nav}"] = fmt.Sprintf(`<nav aria-label="%s">`, args["{$title}"])
|
||||||
|
args["{$navCloser}"] = "</nav>"
|
||||||
|
}
|
||||||
|
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>`)
|
||||||
|
|
|
@ -39,22 +39,29 @@ 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)
|
||||||
commentsArgs := recentCommentsArgs()
|
|
||||||
commonArgs := wp.GetComponentsArgs(h, widgets.Widget, map[string]string{})
|
func RecentCommentArgs(a ...any) map[string]string {
|
||||||
args := wp.GetComponentsArgs(h, widgets.RecentComments, commentsArgs)
|
h := a[0].(*wp.Handle)
|
||||||
args = maps.FilterZeroMerge(commentsArgs, CommonArgs(), commonArgs, args)
|
conf := a[1].(map[any]any)
|
||||||
args["{$before_widget}"] = fmt.Sprintf(args["{$before_widget}"], str.Join("recent-comments-", id), str.Join("widget widget_", "recent_comments"))
|
id := a[2].(string)
|
||||||
args["{$title}"] = str.Join(args["{$before_title}"], conf["title"].(string), args["{$after_title}"])
|
commentsArgs := recentCommentsArgs()
|
||||||
if slice.IsContained(h.CommonThemeMods().ThemeSupport.HTML5, "navigation-widgets") {
|
commonArgs := wp.GetComponentsArgs(widgets.Widget, map[string]string{})
|
||||||
args["{$nav}"] = fmt.Sprintf(`<nav aria-label="%s">`, conf["title"])
|
args := wp.GetComponentsArgs(widgets.RecentComments, commentsArgs)
|
||||||
args["{$navCloser}"] = "</nav>"
|
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"))
|
||||||
return args, true
|
args["{$title}"] = str.Join(args["{$before_title}"], conf["title"].(string), args["{$after_title}"])
|
||||||
})
|
if slice.IsContained(h.CommonThemeMods().ThemeSupport.HTML5, "navigation-widgets") {
|
||||||
|
args["{$nav}"] = fmt.Sprintf(`<nav aria-label="%s">`, conf["title"])
|
||||||
|
args["{$navCloser}"] = "</nav>"
|
||||||
|
}
|
||||||
|
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>
|
||||||
|
|
|
@ -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,28 +43,37 @@ func recentConf() map[any]any {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var GetRecentPostConf = reload.BuildValFnWithAnyParams("widget-recent-posts-conf", RecentPostConf)
|
||||||
|
|
||||||
|
func RecentPostConf(_ ...any) map[any]any {
|
||||||
|
recent := DefaultRecentConf()
|
||||||
|
conf := wpconfig.GetPHPArrayVal[map[any]any]("widget_recent-posts", recent, int64(2))
|
||||||
|
conf = maps.FilterZeroMerge(recent, conf)
|
||||||
|
return conf
|
||||||
|
}
|
||||||
|
|
||||||
|
var GetRecentPostArgs = reload.BuildValFnWithAnyParams("widget-recent-posts-args", ParseRecentPostArgs)
|
||||||
|
|
||||||
|
func ParseRecentPostArgs(a ...any) map[string]string {
|
||||||
|
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["{$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}"])
|
||||||
|
if slice.IsContained(h.CommonThemeMods().ThemeSupport.HTML5, "navigation-widgets") {
|
||||||
|
args["{$nav}"] = fmt.Sprintf(`<nav aria-label="%s">`, conf["title"])
|
||||||
|
args["{$navCloser}"] = "</nav>"
|
||||||
|
}
|
||||||
|
return args
|
||||||
|
}
|
||||||
|
|
||||||
func RecentPosts(h *wp.Handle, id string) string {
|
func RecentPosts(h *wp.Handle, id string) string {
|
||||||
conf := reload.GetAnyValBys("widget-recent-posts-conf", h, func(h *wp.Handle) (map[any]any, bool) {
|
conf := GetRecentPostConf()
|
||||||
recent := recentConf()
|
args := GetRecentPostArgs(h, conf, id)
|
||||||
conf := wpconfig.GetPHPArrayVal[map[any]any]("widget_recent-posts", recent, int64(2))
|
|
||||||
conf = maps.FilterZeroMerge(recent, conf)
|
|
||||||
return conf, true
|
|
||||||
})
|
|
||||||
|
|
||||||
args := reload.GetAnyValBys("widget-recent-posts-args", h, func(h *wp.Handle) (map[string]string, bool) {
|
|
||||||
recent := recentPostsArgs()
|
|
||||||
commonArgs := wp.GetComponentsArgs(h, widgets.Widget, map[string]string{})
|
|
||||||
args := wp.GetComponentsArgs(h, widgets.RecentPosts, recent)
|
|
||||||
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["{$title}"] = str.Join(args["{$before_title}"], conf["title"].(string), args["{$after_title}"])
|
|
||||||
if slice.IsContained(h.CommonThemeMods().ThemeSupport.HTML5, "navigation-widgets") {
|
|
||||||
args["{$nav}"] = fmt.Sprintf(`<nav aria-label="%s">`, conf["title"])
|
|
||||||
args["{$navCloser}"] = "</nav>"
|
|
||||||
}
|
|
||||||
return args, true
|
|
||||||
})
|
|
||||||
|
|
||||||
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))
|
||||||
|
|
|
@ -47,34 +47,40 @@ func searchArgs() map[string]string {
|
||||||
|
|
||||||
var form = html5SearchForm
|
var form = html5SearchForm
|
||||||
|
|
||||||
|
var GetSearchArgs = reload.BuildValFnWithAnyParams("widget-search-args", ParseSearchArgs)
|
||||||
|
|
||||||
|
func ParseSearchArgs(a ...any) map[string]string {
|
||||||
|
h := a[0].(*wp.Handle)
|
||||||
|
id := a[1].(string)
|
||||||
|
search := searchArgs()
|
||||||
|
commonArgs := wp.GetComponentsArgs(widgets.Widget, map[string]string{})
|
||||||
|
args := wp.GetComponentsArgs(widgets.Search, search)
|
||||||
|
args = maps.FilterZeroMerge(search, CommonArgs(), commonArgs, args)
|
||||||
|
args["{$before_widget}"] = fmt.Sprintf(args["{$before_widget}"], str.Join("search-", id), str.Join("widget widget_", "search"))
|
||||||
|
if args["{$title}"] == "" {
|
||||||
|
args["{$title}"] = wpconfig.GetPHPArrayVal("widget_search", "", int64(2), "title")
|
||||||
|
}
|
||||||
|
|
||||||
|
if args["{$title}"] != "" {
|
||||||
|
args["{$title}"] = str.Join(args["{$before_title}"], args["{$title}"], args["{$after_title}"])
|
||||||
|
}
|
||||||
|
if args["{$form}"] != "" {
|
||||||
|
form = args["{$form}"]
|
||||||
|
delete(args, "{$form}")
|
||||||
|
}
|
||||||
|
if !slice.IsContained(h.CommonThemeMods().ThemeSupport.HTML5, "navigation-widgets") {
|
||||||
|
form = xmlSearchForm
|
||||||
|
}
|
||||||
|
|
||||||
|
return args
|
||||||
|
}
|
||||||
|
|
||||||
func Search(h *wp.Handle, id string) string {
|
func Search(h *wp.Handle, id string) string {
|
||||||
args := reload.GetAnyValBys("widget-search-args", h, func(h *wp.Handle) (map[string]string, bool) {
|
args := GetSearchArgs(h, id)
|
||||||
search := searchArgs()
|
|
||||||
commonArgs := wp.GetComponentsArgs(h, widgets.Widget, map[string]string{})
|
|
||||||
args := wp.GetComponentsArgs(h, widgets.Search, search)
|
|
||||||
args = maps.FilterZeroMerge(search, CommonArgs(), commonArgs, args)
|
|
||||||
args["{$before_widget}"] = fmt.Sprintf(args["{$before_widget}"], str.Join("search-", id), str.Join("widget widget_", "search"))
|
|
||||||
if args["{$title}"] == "" {
|
|
||||||
args["{$title}"] = wpconfig.GetPHPArrayVal("widget_search", "", int64(2), "title")
|
|
||||||
}
|
|
||||||
|
|
||||||
if args["{$title}"] != "" {
|
|
||||||
args["{$title}"] = str.Join(args["{$before_title}"], args["{$title}"], args["{$after_title}"])
|
|
||||||
}
|
|
||||||
if args["{$form}"] != "" {
|
|
||||||
form = args["{$form}"]
|
|
||||||
delete(args, "{$form}")
|
|
||||||
}
|
|
||||||
if !slice.IsContained(h.CommonThemeMods().ThemeSupport.HTML5, "navigation-widgets") {
|
|
||||||
form = xmlSearchForm
|
|
||||||
}
|
|
||||||
|
|
||||||
return args, true
|
|
||||||
})
|
|
||||||
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))
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var GetCustomHeaderImgFn = reload.BuildValFnWithConfirm("headerImages", customHeadImag, 5)
|
||||||
|
|
||||||
|
func customHeadImag(h *Handle) ([]models.PostThumbnail, bool) {
|
||||||
|
hs, err := h.GetHeaderImages(h.theme)
|
||||||
|
if err != nil {
|
||||||
|
h.SetErr(err)
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return hs, true
|
||||||
|
}
|
||||||
|
|
||||||
func (h *Handle) GetCustomHeaderImg() (r models.PostThumbnail, isRand bool) {
|
func (h *Handle) GetCustomHeaderImg() (r models.PostThumbnail, isRand bool) {
|
||||||
var err error
|
var err error
|
||||||
img := reload.GetAnyValBy("headerImages", h.theme, func(theme string) ([]models.PostThumbnail, bool) {
|
img := GetCustomHeaderImgFn(h)
|
||||||
hs, er := h.GetHeaderImages(h.theme)
|
err = h.Err()
|
||||||
if er != nil {
|
|
||||||
err = er
|
|
||||||
return nil, false
|
|
||||||
}
|
|
||||||
return hs, true
|
|
||||||
}, 5)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logs.Error(err, "获取页眉背景图失败")
|
logs.Error(err, "获取页眉背景图失败")
|
||||||
return
|
return
|
||||||
|
|
|
@ -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
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)))
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,49 +70,51 @@ func Hook(path string, fn func(Route) Route) {
|
||||||
return r, path == r.Path
|
return r, path == r.Path
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var RegRouteFn = reload.BuildValFnWithAnyParams("regexRoute", RegRouteHook)
|
||||||
|
|
||||||
|
func RegRouteHook(_ ...any) func() (map[string]Route, map[string]*regexp.Regexp) {
|
||||||
|
m := map[string]Route{}
|
||||||
|
rrs := map[string]*regexp.Regexp{}
|
||||||
|
routes.Range(func(key string, value Route) bool {
|
||||||
|
vv, _ := regRoutes.Load(key)
|
||||||
|
if len(routeHook) > 0 {
|
||||||
|
for _, fn := range routeHook {
|
||||||
|
v, ok := fn(value)
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
m[v.Path] = v
|
||||||
|
if v.Type != "reg" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if v.Path != key {
|
||||||
|
vvv, err := regexp.Compile(v.Path)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
vv = vvv
|
||||||
|
}
|
||||||
|
rrs[v.Path] = vv
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
m[key] = value
|
||||||
|
rrs[key] = vv
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
return func() (map[string]Route, map[string]*regexp.Regexp) {
|
||||||
|
return m, rrs
|
||||||
|
}
|
||||||
|
}
|
||||||
func ResolveRoute(h *wp.Handle) {
|
func ResolveRoute(h *wp.Handle) {
|
||||||
requestURI := h.C.Request.RequestURI
|
requestURI := h.C.Request.RequestURI
|
||||||
rs, rrs := reload.GetAnyValBys("route",
|
rs, rrs := RegRouteFn()()
|
||||||
struct{}{},
|
|
||||||
func(_ struct{}) (func() (map[string]Route, map[string]*regexp.Regexp), bool) {
|
|
||||||
m := map[string]Route{}
|
|
||||||
rrs := map[string]*regexp.Regexp{}
|
|
||||||
routes.Range(func(key string, value Route) bool {
|
|
||||||
vv, _ := regRoutes.Load(key)
|
|
||||||
if len(routeHook) > 0 {
|
|
||||||
for _, fn := range routeHook {
|
|
||||||
v, ok := fn(value)
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
m[v.Path] = v
|
|
||||||
if v.Type != "reg" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if v.Path != key {
|
|
||||||
vvv, err := regexp.Compile(v.Path)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
vv = vvv
|
|
||||||
}
|
|
||||||
rrs[v.Path] = vv
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
m[key] = value
|
|
||||||
rrs[key] = vv
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
return func() (map[string]Route, map[string]*regexp.Regexp) {
|
|
||||||
return m, rrs
|
|
||||||
}, true
|
|
||||||
})()
|
|
||||||
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,41 +8,41 @@ 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) {
|
|
||||||
v := wpconfig.GetOption("sticky_posts")
|
func ParseStickPosts(h *Handle) (r []models.Posts, ok bool) {
|
||||||
if v == "" {
|
v := wpconfig.GetOption("sticky_posts")
|
||||||
return
|
if v == "" {
|
||||||
}
|
|
||||||
array, err := phpserialize.UnmarshalIndexedArray([]byte(v))
|
|
||||||
if err != nil {
|
|
||||||
logs.Error(err, "解析option sticky_posts错误", v)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
r = slice.FilterAndMap(array, func(t any) (models.Posts, bool) {
|
|
||||||
id := str.ToInt[uint64](fmt.Sprintf("%v", t))
|
|
||||||
post, err := cache.GetPostById(h.C, id)
|
|
||||||
post.IsSticky = true
|
|
||||||
return post, err == nil
|
|
||||||
})
|
|
||||||
ok = true
|
|
||||||
return
|
return
|
||||||
|
}
|
||||||
|
array, err := phpserialize.UnmarshalIndexedArray([]byte(v))
|
||||||
|
if err != nil {
|
||||||
|
logs.Error(err, "解析option sticky_posts错误", v)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
r = slice.FilterAndMap(array, func(t any) (models.Posts, bool) {
|
||||||
|
id := str.ToInt[uint64](fmt.Sprintf("%v", t))
|
||||||
|
post, err := cache.GetPostById(h.C, id)
|
||||||
|
post.IsSticky = true
|
||||||
|
return post, err == nil
|
||||||
})
|
})
|
||||||
|
ok = true
|
||||||
|
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 v.Id
|
return slice.SimpleToMap(GetStickPosts(h), func(v models.Posts) uint64 {
|
||||||
}), true
|
return v.Id
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,30 +20,26 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Handle struct {
|
type Handle struct {
|
||||||
Index *IndexHandle
|
C *gin.Context
|
||||||
Detail *DetailHandle
|
theme string
|
||||||
C *gin.Context
|
isInited bool
|
||||||
theme string
|
Session sessions.Session
|
||||||
Session sessions.Session
|
ginH gin.H
|
||||||
ginH gin.H
|
password string
|
||||||
password string
|
scene string
|
||||||
scene string
|
Code int
|
||||||
Code int
|
Stats string
|
||||||
Stats string
|
templ string
|
||||||
templ string
|
themeMods wpconfig.ThemeMods
|
||||||
components map[string]map[string][]Components[string]
|
err error
|
||||||
componentHook map[string][]func(Components[string]) (Components[string], bool)
|
abort bool
|
||||||
themeMods wpconfig.ThemeMods
|
stopPipe bool
|
||||||
handlers map[string]map[string][]HandleCall
|
template *template.Template
|
||||||
handleHook map[string][]func(HandleCall) (HandleCall, bool)
|
|
||||||
err error
|
|
||||||
abort bool
|
|
||||||
stopPipe bool
|
|
||||||
componentsArgs map[string]any
|
|
||||||
componentFilterFn map[string][]func(*Handle, string, ...any) string
|
|
||||||
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()
|
||||||
h.ginH = gin.H{}
|
componentsArgs.Flush()
|
||||||
fnMap.Flush()
|
handleComponentHook.Flush()
|
||||||
fnHook.Flush()
|
componentFilterFns.Flush()
|
||||||
fn(h)
|
handlerss.Flush()
|
||||||
v := apply.UsePlugins()
|
handleHooks.Flush()
|
||||||
pluginFn, ok := v.(func(*Handle))
|
h.ginH = gin.H{}
|
||||||
if ok {
|
fnMap.Flush()
|
||||||
pluginFn(h)
|
fnHook.Flush()
|
||||||
}
|
h.C = hh.C
|
||||||
h.C.Set("inited", true)
|
h.theme = hh.theme
|
||||||
inited = true
|
h.template = hh.template
|
||||||
return *h, true
|
configFn(h)
|
||||||
})
|
v := apply.UsePlugins()
|
||||||
|
pluginFn, ok := v.(func(*Handle))
|
||||||
|
if ok {
|
||||||
|
pluginFn(h)
|
||||||
|
}
|
||||||
|
return *h
|
||||||
|
}
|
||||||
|
|
||||||
|
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() {
|
||||||
|
|
10
cache/cachemanager/manger.go
vendored
10
cache/cachemanager/manger.go
vendored
|
@ -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
2
cache/map.go
vendored
|
@ -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
4
cache/map_test.go
vendored
|
@ -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]{
|
||||||
{
|
{
|
||||||
|
|
373
cache/reload/reload.go
vendored
373
cache/reload/reload.go
vendored
|
@ -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, ok = fn(a)
|
||||||
|
if ok {
|
||||||
|
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 {
|
if ok {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
v = fn(a)
|
v = fn(a)
|
||||||
m.val.Store(key, v)
|
m.Val.Store(key, v)
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func safetyMapFn[K comparable, V, A any](namespace string, args ...any) *safetyMap[K, V, A] {
|
// BuildMapFnWithAnyParams same as BuildMapFn use multiple params
|
||||||
vv, ok := safetyMaps.Load(namespace)
|
func BuildMapFnWithAnyParams[K comparable, V any](namespace string, fn func(...any) V, a ...any) func(key K, a ...any) V {
|
||||||
var m *safetyMap[K, V, A]
|
m := BuildSafetyMap[K, V, any](namespace, a...)
|
||||||
if ok {
|
return func(key K, a ...any) V {
|
||||||
m = vv.(*safetyMap[K, V, A])
|
v, ok := m.Val.Load(key)
|
||||||
} else {
|
|
||||||
safetyMapLock.Lock()
|
|
||||||
defer safetyMapLock.Unlock()
|
|
||||||
vv, ok = safetyMaps.Load(namespace)
|
|
||||||
if ok {
|
if ok {
|
||||||
m = vv.(*safetyMap[K, V, A])
|
return v
|
||||||
} 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)
|
|
||||||
}
|
}
|
||||||
|
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
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetAnyValMapBy[K comparable, V, A any](namespace string, key K, a A, fn func(A) (V, bool), args ...any) V {
|
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...)
|
m := BuildSafetyMap[K, V, A](namespace, args...)
|
||||||
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 {
|
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
|
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 {
|
vv.Val.Store(v)
|
||||||
v.counter = number.Counters[int]()
|
return v.V
|
||||||
}
|
|
||||||
times := v.counter()
|
|
||||||
tryTimes := helper.ParseArgs(1, args...)
|
|
||||||
if ok || times >= tryTimes {
|
|
||||||
v.ok = true
|
|
||||||
vv.Val.Store(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...)
|
//
|
||||||
v := vv.Val.Load()
|
// if give a int and value bigger than 1 will be a times which built fn called return false
|
||||||
if v.ok {
|
func BuildValFnWithConfirm[T, A any](namespace string, fn func(A) (T, bool), args ...any) func(A) T {
|
||||||
return v.v
|
var vv = BuildAnyVal[T, A](namespace, false, args...)
|
||||||
|
tryTimes := helper.ParseArgs(1, args...)
|
||||||
|
var counter func() int
|
||||||
|
if tryTimes > 1 {
|
||||||
|
counter = number.Counters[int]()
|
||||||
}
|
}
|
||||||
vv.mutex.Lock()
|
return func(a A) T {
|
||||||
defer vv.mutex.Unlock()
|
v := vv.Val.Load()
|
||||||
v = vv.Val.Load()
|
if v.Ok {
|
||||||
if v.ok {
|
return v.V
|
||||||
return v.v
|
}
|
||||||
|
vv.Mutex.Lock()
|
||||||
|
defer vv.Mutex.Unlock()
|
||||||
|
v = vv.Val.Load()
|
||||||
|
if v.Ok {
|
||||||
|
return v.V
|
||||||
|
}
|
||||||
|
v.V, v.Ok = fn(a)
|
||||||
|
if v.Ok {
|
||||||
|
vv.Val.Store(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
|
||||||
}
|
}
|
||||||
v.v, v.ok = fn(a)
|
|
||||||
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,37 +389,42 @@ 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
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
|
@ -301,23 +434,23 @@ func FnVal[T any](name string, t T, fn func() T) func() T {
|
||||||
}
|
}
|
||||||
p := safety.NewVar(t)
|
p := safety.NewVar(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)
|
||||||
}
|
}
|
||||||
|
|
8
cache/reload/reload_test.go
vendored
8
cache/reload/reload_test.go
vendored
|
@ -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)
|
||||||
})
|
})
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user