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) {
|
||||
t := theme.GetCurrentTemplateName()
|
||||
h := wp.NewHandle(c, scene, t)
|
||||
h.Index = wp.NewIndexHandle(h)
|
||||
h.Detail = wp.NewDetailHandle(h)
|
||||
templ, _ := theme.GetTemplate(t)
|
||||
h.SetTemplate(templ)
|
||||
theme.Hook(t, h)
|
||||
|
|
|
@ -19,9 +19,9 @@ func FlowLimit(maxRequestSleepNum, maxRequestNum int64, sleepTime []time.Duratio
|
|||
}
|
||||
s := safety.Var[[]time.Duration]{}
|
||||
s.Store(sleepTime)
|
||||
fn := func(msn, mn int64, st []time.Duration) {
|
||||
atomic.StoreInt64(&maxRequestSleepNum, msn)
|
||||
atomic.StoreInt64(&maxRequestNum, mn)
|
||||
fn := func(sleepNum, maxNum int64, st []time.Duration) {
|
||||
atomic.StoreInt64(&maxRequestSleepNum, sleepNum)
|
||||
atomic.StoreInt64(&maxRequestNum, maxNum)
|
||||
s.Store(st)
|
||||
}
|
||||
return func(c *gin.Context) {
|
||||
|
|
|
@ -25,14 +25,25 @@ func IpLimit(num int64) (func(ctx *gin.Context), func(int64)) {
|
|||
fn(num)
|
||||
|
||||
return func(c *gin.Context) {
|
||||
if atomic.LoadInt64(m.limitNum) <= 0 {
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
ip := c.ClientIP()
|
||||
s := false
|
||||
m.mux.RLock()
|
||||
i, ok := m.m[ip]
|
||||
m.mux.RUnlock()
|
||||
|
||||
if !ok {
|
||||
m.mux.Lock()
|
||||
i = new(int64)
|
||||
m.m[ip] = i
|
||||
m.mux.Unlock()
|
||||
}
|
||||
|
||||
defer func() {
|
||||
ii := atomic.LoadInt64(i)
|
||||
if s && ii > 0 {
|
||||
if ii > 0 {
|
||||
atomic.AddInt64(i, -1)
|
||||
if atomic.LoadInt64(i) == 0 {
|
||||
m.mux.Lock()
|
||||
|
@ -42,20 +53,12 @@ func IpLimit(num int64) (func(ctx *gin.Context), func(int64)) {
|
|||
}
|
||||
}()
|
||||
|
||||
if !ok {
|
||||
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) {
|
||||
if atomic.LoadInt64(i) >= atomic.LoadInt64(m.limitNum) {
|
||||
c.Status(http.StatusForbidden)
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
atomic.AddInt64(i, 1)
|
||||
s = true
|
||||
c.Next()
|
||||
}, fn
|
||||
}
|
||||
|
|
|
@ -39,9 +39,11 @@ func InitDb() (*safety.Var[*sqlx.DB], error) {
|
|||
if preDb != nil {
|
||||
_ = preDb.Close()
|
||||
}
|
||||
showQuerySql = reload.FnVal("showQuerySql", false, func() bool {
|
||||
return config.GetConfig().ShowQuerySql
|
||||
})
|
||||
if showQuerySql == nil {
|
||||
showQuerySql = reload.BuildFnVal("showQuerySql", false, func() bool {
|
||||
return config.GetConfig().ShowQuerySql
|
||||
})
|
||||
}
|
||||
return safeDb, err
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ func configs(h *wp.Handle) {
|
|||
})
|
||||
wp.InitPipe(h)
|
||||
middleware.CommonMiddleware(h)
|
||||
h.Index.SetPageEle(plugins.TwentyFifteenPagination())
|
||||
setPaginationAndRender(h)
|
||||
h.PushCacheGroupHeadScript(constraints.AllScene, "CalCustomBackGround", 10.005, CalCustomBackGround)
|
||||
h.PushCacheGroupHeadScript(constraints.AllScene, "colorSchemeCss", 10.0056, colorSchemeCss)
|
||||
h.CommonComponents()
|
||||
|
@ -39,8 +39,22 @@ func configs(h *wp.Handle) {
|
|||
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) {
|
||||
if h.Detail.Post.Thumbnail.Path != "" {
|
||||
h.Detail.Post.Thumbnail = wpconfig.Thumbnail(h.Detail.Post.Thumbnail.OriginAttachmentData, "post-thumbnail", "")
|
||||
d := h.GetDetailHandle()
|
||||
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)
|
||||
pushScripts(h)
|
||||
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">`,
|
||||
"{$after_widget}": `</section>`,
|
||||
})
|
||||
|
@ -67,13 +67,11 @@ func configs(h *wp.Handle) {
|
|||
)
|
||||
videoHeader(h)
|
||||
h.SetData("colophon", colophon)
|
||||
h.Detail.CommentRender = commentFormat
|
||||
h.Detail.CommentPageEle = commentPageEle
|
||||
setPaginationAndRender(h)
|
||||
h.CommonComponents()
|
||||
h.Index.SetPageEle(paginate)
|
||||
wp.ReplyCommentJs(h)
|
||||
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"))
|
||||
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"))
|
||||
|
@ -81,6 +79,18 @@ func configs(h *wp.Handle) {
|
|||
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="/">
|
||||
<label for="search-form-1">
|
||||
<span class="screen-reader-text">{$label}:</span>
|
||||
|
@ -101,7 +111,7 @@ func errorsHandle(h *wp.Handle) {
|
|||
}
|
||||
|
||||
func postThumb(h *wp.Handle) {
|
||||
d := h.Detail
|
||||
d := h.GetDetailHandle()
|
||||
if d.Post.Thumbnail.Path != "" {
|
||||
img := wpconfig.Thumbnail(d.Post.Thumbnail.OriginAttachmentData, "full", "", "thumbnail", "post-thumbnail")
|
||||
img.Sizes = "100vw"
|
||||
|
|
|
@ -33,14 +33,14 @@ func (h *Handle) BodyClass() string {
|
|||
|
||||
case constraints.Search:
|
||||
s := "search-no-results"
|
||||
if len(h.Index.Posts) > 0 {
|
||||
if len(h.GetIndexHandle().Posts) > 0 {
|
||||
s = "search-results"
|
||||
}
|
||||
class = append(class, "search", s)
|
||||
|
||||
case constraints.Category, constraints.Tag:
|
||||
class = append(class, "archive", "category")
|
||||
cat := h.Index.Param.Category
|
||||
cat := h.GetIndexHandle().Param.Category
|
||||
if cat == "" {
|
||||
break
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ func (h *Handle) BodyClass() string {
|
|||
|
||||
case constraints.Author:
|
||||
class = append(class, "archive", "author")
|
||||
author := h.Index.Param.Author
|
||||
author := h.GetIndexHandle().Param.Author
|
||||
user, _ := cache.GetUserByName(h.C, author)
|
||||
class = append(class, str.Join("author-", number.IntToString(user.Id)))
|
||||
if user.DisplayName[0] != '%' {
|
||||
|
@ -63,7 +63,7 @@ func (h *Handle) BodyClass() string {
|
|||
|
||||
case constraints.Detail:
|
||||
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 {
|
||||
class = append(class, "single-format-standard")
|
||||
}
|
||||
|
|
|
@ -6,57 +6,106 @@ import (
|
|||
"github.com/fthvgb1/wp-go/helper/maps"
|
||||
"github.com/fthvgb1/wp-go/helper/slice"
|
||||
str "github.com/fthvgb1/wp-go/helper/strings"
|
||||
"github.com/fthvgb1/wp-go/safety"
|
||||
"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) {
|
||||
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
|
||||
})
|
||||
handleComponentHook.Store(scene, v)
|
||||
}
|
||||
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 {
|
||||
c = components
|
||||
}
|
||||
return c, true
|
||||
})
|
||||
handleComponentHook.Store(scene, v)
|
||||
}
|
||||
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) {
|
||||
componentss := reload.GetAnyValMapBy("scene-components", str.Join("allScene-", h.scene), h, func(h *Handle) (map[string][]Components[string], bool) {
|
||||
return maps.MergeBy(func(k string, v1, v2 []Components[string]) ([]Components[string], bool) {
|
||||
vv := append(v1, v2...)
|
||||
return vv, vv != nil
|
||||
}, nil, h.components[h.scene], h.components[constraints.AllScene]), true
|
||||
})
|
||||
for k, components := range componentss {
|
||||
allComponents := getComponentFn(str.Join("allScene-", h.scene), h)
|
||||
for k, components := range allComponents {
|
||||
key := str.Join("calComponents-", h.scene, "-", k)
|
||||
ss := reload.GetAnyValMapBy("calComponents", key, h, func(h *Handle) ([]Components[string], bool) {
|
||||
r := slice.FilterAndMap(components, func(t Components[string]) (Components[string], bool) {
|
||||
fns, ok := h.componentHook[k]
|
||||
if !ok {
|
||||
return t, true
|
||||
}
|
||||
for _, fn := range fns {
|
||||
c, ok := fn(t)
|
||||
if !ok {
|
||||
return c, false
|
||||
}
|
||||
t = c
|
||||
}
|
||||
return t, true
|
||||
})
|
||||
slice.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 {
|
||||
hookedComponents := hookComponentFn(key, componentParam{components, k})
|
||||
var s = make([]string, 0, len(hookedComponents))
|
||||
for _, component := range hookedComponents {
|
||||
if component.Val != "" {
|
||||
s = append(s, component.Val)
|
||||
continue
|
||||
|
@ -64,9 +113,7 @@ func CalComponents(h *Handle) {
|
|||
if component.Fn != nil {
|
||||
v := ""
|
||||
if component.Cached {
|
||||
v = reload.GetAnyValMapBy("cacheComponents", component.Name, h, func(a *Handle) (string, bool) {
|
||||
return component.Fn(h), true
|
||||
})
|
||||
v = cacheComponentsFn(component.Name, cacheComponentParm[string]{component, h})
|
||||
} else {
|
||||
v = component.Fn(h)
|
||||
}
|
||||
|
@ -80,12 +127,12 @@ func CalComponents(h *Handle) {
|
|||
}
|
||||
|
||||
func (h *Handle) PushComponents(scene, componentType string, components ...Components[string]) {
|
||||
c, ok := h.components[scene]
|
||||
c, ok := handleComponents.Load(scene)
|
||||
if !ok {
|
||||
c = make(map[string][]Components[string])
|
||||
h.components[scene] = c
|
||||
}
|
||||
c[componentType] = append(c[componentType], components...)
|
||||
handleComponents.Store(scene, c)
|
||||
}
|
||||
|
||||
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...)
|
||||
}
|
||||
|
||||
func GetComponentsArgs[T any](h *Handle, k string, defaults T) T {
|
||||
v, ok := h.componentsArgs[k]
|
||||
func GetComponentsArgs[T any](k string, defaults T) T {
|
||||
v, ok := componentsArgs.Load(k)
|
||||
if ok {
|
||||
vv, ok := v.(T)
|
||||
if ok {
|
||||
|
@ -152,60 +199,61 @@ func GetComponentsArgs[T any](h *Handle, k string, defaults T) T {
|
|||
return defaults
|
||||
}
|
||||
|
||||
func PushComponentsArgsForSlice[T any](h *Handle, name string, v ...T) {
|
||||
val, ok := h.componentsArgs[name]
|
||||
func PushComponentsArgsForSlice[T any](name string, v ...T) {
|
||||
val, ok := componentsArgs.Load(name)
|
||||
if !ok {
|
||||
var vv []T
|
||||
vv = append(vv, v...)
|
||||
h.componentsArgs[name] = vv
|
||||
componentsArgs.Store(name, vv)
|
||||
return
|
||||
}
|
||||
vv, ok := val.([]T)
|
||||
if ok {
|
||||
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) {
|
||||
val, ok := h.componentsArgs[name]
|
||||
func SetComponentsArgsForMap[K comparable, V any](name string, key K, v V) {
|
||||
val, ok := componentsArgs.Load(name)
|
||||
if !ok {
|
||||
vv := make(map[K]V)
|
||||
vv[key] = v
|
||||
h.componentsArgs[name] = vv
|
||||
componentsArgs.Store(name, vv)
|
||||
return
|
||||
}
|
||||
vv, ok := val.(map[K]V)
|
||||
if ok {
|
||||
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) {
|
||||
val, ok := h.componentsArgs[name]
|
||||
func MergeComponentsArgsForMap[K comparable, V any](name string, m map[K]V) {
|
||||
val, ok := componentsArgs.Load(name)
|
||||
if !ok {
|
||||
h.componentsArgs[name] = m
|
||||
componentsArgs.Store(name, m)
|
||||
return
|
||||
}
|
||||
vv, ok := val.(map[K]V)
|
||||
if ok {
|
||||
h.componentsArgs[name] = maps.Merge(vv, m)
|
||||
componentsArgs.Store(name, maps.Merge(vv, m))
|
||||
}
|
||||
}
|
||||
|
||||
func SetComponentsArgs(h *Handle, key string, value any) {
|
||||
h.componentsArgs[key] = value
|
||||
func SetComponentsArgs(key string, value any) {
|
||||
componentsArgs.Store(key, value)
|
||||
}
|
||||
|
||||
func (h *Handle) ComponentFilterFn(name string) ([]func(*Handle, string, ...any) string, bool) {
|
||||
fn, ok := h.componentFilterFn[name]
|
||||
return fn, ok
|
||||
func (h *Handle) GetComponentFilterFn(name string) ([]func(*Handle, string, ...any) string, bool) {
|
||||
return componentFilterFns.Load(name)
|
||||
}
|
||||
|
||||
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 {
|
||||
calls, ok := h.componentFilterFn[name]
|
||||
calls, ok := componentFilterFns.Load(name)
|
||||
if ok {
|
||||
return slice.Reduce(calls, func(fn func(*Handle, string, ...any) string, r string) string {
|
||||
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
|
||||
class := maps.GetAnyAnyValWithDefaults(attr, "", "className")
|
||||
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")
|
||||
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)
|
||||
if !ok {
|
||||
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(`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) {
|
||||
counter := number.Counters[int]()
|
||||
var err error
|
||||
conf := reload.GetAnyValBy("block-category-conf", h, func(h *wp.Handle) (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
|
||||
}, 5)
|
||||
conf := GetCategoryConf(blockParser)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -127,10 +140,7 @@ func Category(h *wp.Handle, id string, blockParser ParserBlock) (func() string,
|
|||
if maps.GetAnyAnyValWithDefaults(conf, false, "showOnlyTopLevel") {
|
||||
h.C.Set("showOnlyTopLevel", true)
|
||||
}
|
||||
args := reload.GetAnyValBys("block-category-args", h, func(h *wp.Handle) (map[string]string, bool) {
|
||||
args := wp.GetComponentsArgs(h, widgets.Widget, map[string]string{})
|
||||
return maps.FilterZeroMerge(categoryDefaultArgs(), args), true
|
||||
})
|
||||
args := GetCategoryArgs()
|
||||
|
||||
return func() string {
|
||||
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}"])
|
||||
}
|
||||
|
||||
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()
|
||||
li := widget.CategoryLi(h, conf, categories)
|
||||
attrs := reload.GetAnyValBys("block-category-attr", conf, parseAttr)
|
||||
li := widget.CategoryLi(h, confAttr, categories)
|
||||
attrs := GetCategoryAttr(confAttr)
|
||||
s.Sprintf(`<ul %s>%s</ul>`, attrs, li)
|
||||
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()
|
||||
ids := fmt.Sprintf(`wp-block-categories-%v`, id)
|
||||
args = maps.Copy(args)
|
||||
args["{$selectId}"] = ids
|
||||
attrs := reload.GetAnyValBys("block-category-attr", conf, parseAttr)
|
||||
selects := widget.DropdownCategories(h, args, conf, categories)
|
||||
attrs := GetCategoryAttr(confAttr)
|
||||
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))
|
||||
return s.String()
|
||||
}
|
||||
|
|
|
@ -40,21 +40,29 @@ var archivesConfig = map[any]any{
|
|||
"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 {
|
||||
conf := configs(archivesConfig, "widget_archives", int64(2))
|
||||
args := reload.GetAnyValBys("widget-archive-args", h, func(h *wp.Handle) (map[string]string, bool) {
|
||||
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
|
||||
})
|
||||
conf := GetArchiveConf()
|
||||
args := GetArchiveArgs(h, conf, id)
|
||||
|
||||
s := archiveTemplate
|
||||
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 {
|
||||
option := str.NewBuilder()
|
||||
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)
|
||||
for _, archive := range archives {
|
||||
sel := ""
|
||||
if h.Index.Param.Year == archive.Year && month == archive.Month {
|
||||
if i.Param.Year == archive.Year && month == archive.Month {
|
||||
sel = "selected"
|
||||
}
|
||||
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 {
|
||||
conf := configs(categoryConfig, "widget_categories", int64(2))
|
||||
|
||||
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
|
||||
})
|
||||
|
||||
conf := GetCategoryConf()
|
||||
args := GetCategoryArgs(h, conf, id)
|
||||
t := categoryTemplate
|
||||
dropdown := conf["dropdown"].(int64)
|
||||
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>
|
||||
`, args["{$show_option_none}"])
|
||||
currentCategory := ""
|
||||
i := h.GetIndexHandle()
|
||||
if h.Scene() == constraints.Category {
|
||||
currentCategory = h.Index.Param.Category
|
||||
currentCategory = i.Param.Category
|
||||
}
|
||||
showCount := conf["count"].(int64)
|
||||
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) {
|
||||
cate := wp.GetComponentsArgs[map[string]string](h, widgets.Categories, categoryArgs())
|
||||
cate := wp.GetComponentsArgs[map[string]string](widgets.Categories, categoryArgs())
|
||||
name, ok := cate["{$name}"]
|
||||
if !ok || name == "" {
|
||||
return
|
||||
|
@ -260,7 +268,7 @@ func IsCategory(h *wp.Handle) (category models.TermsMy, r bool) {
|
|||
}
|
||||
|
||||
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}"]
|
||||
if ok {
|
||||
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 {
|
||||
return reload.GetAnyValBys(str.Join("widget-config-", key), key, func(_ string) (M, bool) {
|
||||
c := wpconfig.GetPHPArrayVal[M](key, nil, a...)
|
||||
return maps.FilterZeroMerge(maps.Copy(m), c), true
|
||||
})
|
||||
func configFns[K comparable, V any](m map[K]V, key string, a ...any) func(_ ...any) map[K]V {
|
||||
return func(_ ...any) map[K]V {
|
||||
c := wpconfig.GetPHPArrayVal[map[K]V](key, nil, a...)
|
||||
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}
|
||||
{$after_widget}`
|
||||
|
||||
func metaArgs() map[string]string {
|
||||
func defaultMetaArgs() map[string]string {
|
||||
return map[string]string{
|
||||
"{$aria_label}": "",
|
||||
"{$title}": "",
|
||||
}
|
||||
}
|
||||
|
||||
func Meta(h *wp.Handle, id string) string {
|
||||
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
|
||||
})
|
||||
var GetMetaArgs = reload.BuildValFnWithAnyParams("widget-meta-args", ParseMetaArgs)
|
||||
|
||||
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()
|
||||
if str.ToInteger(wpconfig.GetOption("users_can_register"), 0) > 0 {
|
||||
ss.Sprintf(`<li><a href="/wp-login.php?action=register">注册</li>`)
|
||||
|
|
|
@ -39,22 +39,29 @@ var recentCommentsTemplate = `{$before_widget}
|
|||
{$after_widget}
|
||||
`
|
||||
|
||||
func RecentComments(h *wp.Handle, id string) string {
|
||||
conf := configs(recentCommentConf, "widget_recent-comments", int64(2))
|
||||
var GetRecentCommentConf = BuildconfigFn(recentCommentConf, "widget_recent-comments", int64(2))
|
||||
|
||||
args := reload.GetAnyValBys("widget-recent-comment-args", h, func(h *wp.Handle) (map[string]string, bool) {
|
||||
commentsArgs := recentCommentsArgs()
|
||||
commonArgs := wp.GetComponentsArgs(h, widgets.Widget, map[string]string{})
|
||||
args := wp.GetComponentsArgs(h, widgets.RecentComments, commentsArgs)
|
||||
args = maps.FilterZeroMerge(commentsArgs, CommonArgs(), commonArgs, args)
|
||||
args["{$before_widget}"] = fmt.Sprintf(args["{$before_widget}"], str.Join("recent-comments-", id), str.Join("widget widget_", "recent_comments"))
|
||||
args["{$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
|
||||
})
|
||||
var GetRecentCommentArgs = reload.BuildValFnWithAnyParams("widget-recent-comment-args", RecentCommentArgs)
|
||||
|
||||
func RecentCommentArgs(a ...any) map[string]string {
|
||||
h := a[0].(*wp.Handle)
|
||||
conf := a[1].(map[any]any)
|
||||
id := a[2].(string)
|
||||
commentsArgs := recentCommentsArgs()
|
||||
commonArgs := wp.GetComponentsArgs(widgets.Widget, map[string]string{})
|
||||
args := wp.GetComponentsArgs(widgets.RecentComments, commentsArgs)
|
||||
args = maps.FilterZeroMerge(commentsArgs, CommonArgs(), commonArgs, args)
|
||||
args["{$before_widget}"] = fmt.Sprintf(args["{$before_widget}"], str.Join("recent-comments-", id), str.Join("widget widget_", "recent_comments"))
|
||||
args["{$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 {
|
||||
return fmt.Sprintf(` <li>
|
||||
|
|
|
@ -25,7 +25,7 @@ var recentPostsTemplate = `{$before_widget}
|
|||
{$after_widget}
|
||||
`
|
||||
|
||||
func recentPostsArgs() map[string]string {
|
||||
func DefaultRecentPostsArgs() map[string]string {
|
||||
return map[string]string{
|
||||
"{$before_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{
|
||||
"number": int64(5),
|
||||
"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 {
|
||||
conf := reload.GetAnyValBys("widget-recent-posts-conf", h, func(h *wp.Handle) (map[any]any, bool) {
|
||||
recent := recentConf()
|
||||
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
|
||||
})
|
||||
|
||||
conf := GetRecentPostConf()
|
||||
args := GetRecentPostArgs(h, conf, id)
|
||||
currentPostId := uint64(0)
|
||||
if h.Scene() == constraints.Detail {
|
||||
currentPostId = str.ToInteger(h.C.Param("id"), uint64(0))
|
||||
|
|
|
@ -47,34 +47,40 @@ func searchArgs() map[string]string {
|
|||
|
||||
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 {
|
||||
args := reload.GetAnyValBys("widget-search-args", h, func(h *wp.Handle) (map[string]string, bool) {
|
||||
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
|
||||
})
|
||||
args := GetSearchArgs(h, id)
|
||||
s := strings.ReplaceAll(searchTemplate, "{$form}", form)
|
||||
val := ""
|
||||
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)
|
||||
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
|
||||
}
|
||||
|
||||
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) {
|
||||
var err error
|
||||
img := reload.GetAnyValBy("headerImages", h.theme, func(theme string) ([]models.PostThumbnail, bool) {
|
||||
hs, er := h.GetHeaderImages(h.theme)
|
||||
if er != nil {
|
||||
err = er
|
||||
return nil, false
|
||||
}
|
||||
return hs, true
|
||||
}, 5)
|
||||
img := GetCustomHeaderImgFn(h)
|
||||
err = h.Err()
|
||||
if err != nil {
|
||||
logs.Error(err, "获取页眉背景图失败")
|
||||
return
|
||||
|
|
|
@ -42,10 +42,10 @@ func CalCustomLogo(h *Handle) (r string) {
|
|||
return
|
||||
}
|
||||
|
||||
var GetCustomLog = reload.BuildValFn("customLogo", CalCustomLogo)
|
||||
|
||||
func customLogo(h *Handle) func() string {
|
||||
return func() string {
|
||||
return reload.GetAnyValBys("customLogo", h, func(h *Handle) (string, bool) {
|
||||
return CalCustomLogo(h), true
|
||||
})
|
||||
return GetCustomLog(h)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
d.ginH["totalCommentNum"] = 0
|
||||
d.ginH["totalCommentPage"] = 1
|
||||
|
@ -170,16 +179,17 @@ func DetailRender(h *Handle) {
|
|||
if h.Stats != constraints.Ok {
|
||||
return
|
||||
}
|
||||
d := h.Detail
|
||||
d := h.GetDetailHandle()
|
||||
d.PasswordProject()
|
||||
d.RenderComment()
|
||||
d.ginH["post"] = d.Post
|
||||
}
|
||||
|
||||
func Detail(h *Handle) {
|
||||
err := h.Detail.BuildDetailData()
|
||||
d := h.GetDetailHandle()
|
||||
err := d.BuildDetailData()
|
||||
if err != nil {
|
||||
h.Detail.SetErr(err)
|
||||
d.SetErr(err)
|
||||
}
|
||||
h.SetData("scene", h.Scene())
|
||||
}
|
||||
|
@ -187,7 +197,7 @@ func Detail(h *Handle) {
|
|||
func ReplyCommentJs(h *Handle) {
|
||||
h.PushFooterScript(constraints.Detail, NewComponent("comment-reply.js", "", false, 10, func(h *Handle) string {
|
||||
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>`
|
||||
}
|
||||
return reply
|
||||
|
|
|
@ -25,6 +25,16 @@ type IndexHandle struct {
|
|||
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) {
|
||||
return i.postsPlugin
|
||||
}
|
||||
|
@ -120,8 +130,11 @@ func (i *IndexHandle) Pagination() {
|
|||
|
||||
}
|
||||
|
||||
func (i *IndexHandle) BuildIndexData(parm *IndexParams) (err error) {
|
||||
err = i.ParseIndex(parm)
|
||||
func (i *IndexHandle) BuildIndexData() (err error) {
|
||||
if i.Param == nil {
|
||||
i.Param = NewIndexParams(i.C)
|
||||
}
|
||||
err = i.ParseIndex(i.Param)
|
||||
if err != nil {
|
||||
i.Stats = constraints.ParamError
|
||||
return
|
||||
|
@ -137,12 +150,12 @@ func (i *IndexHandle) BuildIndexData(parm *IndexParams) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
var GetPostsPlugin = reload.BuildValFnWithAnyParams("postPlugins", UsePostsPlugins)
|
||||
|
||||
func (i *IndexHandle) ExecPostsPlugin() {
|
||||
fn := i.postsPlugin
|
||||
if fn == nil {
|
||||
fn = reload.GetAnyValBys("postPlugins", i, func(a *IndexHandle) (PostsPlugin, bool) {
|
||||
return UsePostsPlugins(), true
|
||||
})
|
||||
fn = GetPostsPlugin()
|
||||
}
|
||||
for j := range i.Posts {
|
||||
fn(i.Handle, &i.Posts[j])
|
||||
|
@ -150,15 +163,15 @@ func (i *IndexHandle) ExecPostsPlugin() {
|
|||
}
|
||||
|
||||
func IndexRender(h *Handle) {
|
||||
i := h.Index
|
||||
i := h.GetIndexHandle()
|
||||
i.ExecPostsPlugin()
|
||||
i.Pagination()
|
||||
i.ginH["posts"] = i.Posts
|
||||
}
|
||||
|
||||
func Index(h *Handle) {
|
||||
i := h.Index
|
||||
err := i.BuildIndexData(NewIndexParams(i.C))
|
||||
i := h.GetIndexHandle()
|
||||
err := i.BuildIndexData()
|
||||
if err != nil {
|
||||
i.SetErr(err)
|
||||
}
|
||||
|
@ -166,11 +179,11 @@ func Index(h *Handle) {
|
|||
}
|
||||
|
||||
func (i *IndexHandle) MarkSticky(posts *[]models.Posts) {
|
||||
a := i.StickPosts()
|
||||
a := GetStickPosts(i.Handle)
|
||||
if len(a) < 1 {
|
||||
return
|
||||
}
|
||||
m := i.StickMapPosts()
|
||||
m := GetStickMapPosts(i.Handle)
|
||||
*posts = append(a, slice.Filter(*posts, func(post models.Posts, _ int) bool {
|
||||
_, ok := m[post.Id]
|
||||
return !ok
|
||||
|
|
|
@ -69,7 +69,7 @@ func PostPlugin(calls ...PostsPlugin) PostsPlugin {
|
|||
}
|
||||
}
|
||||
|
||||
func UsePostsPlugins() PostsPlugin {
|
||||
func UsePostsPlugins(_ ...any) PostsPlugin {
|
||||
m := pluginFns.Load()
|
||||
pluginss := slice.FilterAndMap(config.GetConfig().ListPagePlugins, func(t string) (func(PostsPlugin, *Handle, *models.Posts), bool) {
|
||||
f, ok := m[t]
|
||||
|
|
|
@ -71,14 +71,7 @@ var plainRouteParam = reload.Vars([]Plain{
|
|||
if u == "" {
|
||||
return false
|
||||
}
|
||||
users := reload.GetAnyValBys("usersIds", struct{}{},
|
||||
func(_ struct{}) (map[uint64]string, bool) {
|
||||
users, err := cache.GetAllUsername(h.C)
|
||||
if err != nil {
|
||||
return nil, true
|
||||
}
|
||||
return maps.Flip(users), true
|
||||
})
|
||||
users := GetUsersIds(h)
|
||||
name, ok := users[str.ToInteger[uint64](u, 0)]
|
||||
if !ok {
|
||||
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) {
|
||||
plainRouteParam.Store(p)
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ package wp
|
|||
import (
|
||||
"github.com/fthvgb1/wp-go/app/pkg/constraints"
|
||||
"github.com/fthvgb1/wp-go/cache/reload"
|
||||
"github.com/fthvgb1/wp-go/helper"
|
||||
"github.com/fthvgb1/wp-go/helper/slice"
|
||||
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) {
|
||||
if _, ok := h.handlers[pipScene]; !ok {
|
||||
h.handlers[pipScene] = make(map[string][]HandleCall)
|
||||
v, ok := handlerss.Load(pipScene)
|
||||
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) {
|
||||
|
@ -65,27 +66,14 @@ func (h *Handle) PushDataHandler(scene string, fns ...HandleCall) {
|
|||
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) {
|
||||
key := keyFn(h, pipeScene)
|
||||
handlers := reload.GetAnyValMapBy("pipeHandlers", key, h, func(h *Handle) ([]HandleCall, bool) {
|
||||
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
|
||||
})
|
||||
handlers := pipeHandlerFn(key, h)
|
||||
for _, handler := range handlers {
|
||||
handler.Fn(h)
|
||||
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 {
|
||||
key := str.Join("pipekey", "-", pipScene, "-", h.scene, "-", h.Stats)
|
||||
return h.DoActionFilter("pipeKey", key, pipScene)
|
||||
}
|
||||
|
||||
var pipeInitFn = reload.BuildMapFn[string]("pipeInit", BuildPipe)
|
||||
|
||||
func Run(h *Handle, conf func(*Handle)) {
|
||||
if !helper.GetContextVal(h.C, "inited", false) {
|
||||
if !h.isInited {
|
||||
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) {
|
||||
p := GetFn[Pipe]("pipe", constraints.AllScene)
|
||||
p = append(p, GetFn[Pipe]("pipe", h.scene)...)
|
||||
pipes := slice.FilterAndMap(p, func(pipe Pipe) (Pipe, bool) {
|
||||
func BuildPipe(scene string) func(*Handle) {
|
||||
pipees := GetFn[Pipe]("pipe", constraints.AllScene)
|
||||
pipees = append(pipees, GetFn[Pipe]("pipe", scene)...)
|
||||
pipes := slice.FilterAndMap(pipees, func(pipe Pipe) (Pipe, bool) {
|
||||
var ok bool
|
||||
mut := reload.GetGlobeMutex()
|
||||
mut.Lock()
|
||||
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 {
|
||||
pipe, ok = fn(pipe)
|
||||
if !ok {
|
||||
|
@ -132,7 +153,7 @@ func BuildPipeAndHandler(h *Handle) (func(*Handle), bool) {
|
|||
arr := slice.Map(pipes, func(t Pipe) HandlePipeFn[*Handle] {
|
||||
return t.Fn
|
||||
})
|
||||
return HandlePipe(NothingToDo, arr...), true
|
||||
return HandlePipe(NothingToDo, arr...)
|
||||
}
|
||||
|
||||
func MiddlewareKey(h *Handle, pipScene string) string {
|
||||
|
@ -164,24 +185,30 @@ func PipeRender(h *Handle, renders map[string][]HandleCall, key string) (handler
|
|||
|
||||
// DeleteHandle 写插件的时候用
|
||||
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
|
||||
})
|
||||
handleHooks.Store(pipeScene, v)
|
||||
}
|
||||
|
||||
// ReplaceHandle 写插件的时候用
|
||||
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 {
|
||||
call.Fn = fn
|
||||
}
|
||||
return call, true
|
||||
})
|
||||
handleHooks.Store(pipeScene, v)
|
||||
}
|
||||
|
||||
// HookHandle 写插件的时候用
|
||||
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 {
|
||||
|
@ -197,10 +224,10 @@ func (h *Handle) PipeHandleHook(name string, calls []HandleCall, m map[string][]
|
|||
|
||||
func InitPipe(h *Handle) {
|
||||
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,
|
||||
BuildPipe(constraints.PipeData, PipeKey, PipeDataHandle)))
|
||||
BuildHandlers(constraints.PipeData, PipeKey, PipeDataHandle)))
|
||||
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
|
||||
})
|
||||
}
|
||||
|
||||
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) {
|
||||
requestURI := h.C.Request.RequestURI
|
||||
rs, rrs := reload.GetAnyValBys("route",
|
||||
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
|
||||
})()
|
||||
rs, rrs := RegRouteFn()()
|
||||
v, ok := rs[requestURI]
|
||||
if ok && slice.IsContained(v.Method, h.C.Request.Method) {
|
||||
h.SetScene(v.Scene)
|
||||
wp.Run(h, nil)
|
||||
h.Abort()
|
||||
return
|
||||
}
|
||||
for path, reg := range rrs {
|
||||
|
@ -125,6 +127,7 @@ func ResolveRoute(h *wp.Handle) {
|
|||
h.SetScene(rr.Scene)
|
||||
h.C.Set("route", r)
|
||||
wp.Run(h, nil)
|
||||
h.Abort()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,41 +8,41 @@ import (
|
|||
"github.com/fthvgb1/wp-go/app/pkg/models"
|
||||
"github.com/fthvgb1/wp-go/app/wpconfig"
|
||||
"github.com/fthvgb1/wp-go/cache/reload"
|
||||
"github.com/fthvgb1/wp-go/helper/maps"
|
||||
"github.com/fthvgb1/wp-go/helper/slice"
|
||||
str "github.com/fthvgb1/wp-go/helper/strings"
|
||||
)
|
||||
|
||||
func (h *Handle) StickPosts() []models.Posts {
|
||||
return reload.GetAnyValBys("stickPostsSlice", h, func(h *Handle) (r []models.Posts, ok bool) {
|
||||
v := wpconfig.GetOption("sticky_posts")
|
||||
if v == "" {
|
||||
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
|
||||
var GetStickPosts = reload.BuildValFnWithConfirm("stickPostsSlice", ParseStickPosts)
|
||||
|
||||
func ParseStickPosts(h *Handle) (r []models.Posts, ok bool) {
|
||||
v := wpconfig.GetOption("sticky_posts")
|
||||
if v == "" {
|
||||
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 {
|
||||
return reload.GetAnyValBys("stickPostsMap", h, func(h *Handle) (map[uint64]models.Posts, bool) {
|
||||
return slice.SimpleToMap(h.StickPosts(), func(v models.Posts) uint64 {
|
||||
return v.Id
|
||||
}), true
|
||||
var GetStickMapPosts = reload.BuildValFn("stickPostsMap", StickMapPosts)
|
||||
|
||||
func StickMapPosts(h *Handle) map[uint64]models.Posts {
|
||||
return slice.SimpleToMap(GetStickPosts(h), func(v models.Posts) uint64 {
|
||||
return v.Id
|
||||
})
|
||||
}
|
||||
|
||||
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/helper/maps"
|
||||
str "github.com/fthvgb1/wp-go/helper/strings"
|
||||
"github.com/fthvgb1/wp-go/safety"
|
||||
"github.com/gin-contrib/sessions"
|
||||
"github.com/gin-gonic/gin"
|
||||
"html/template"
|
||||
|
@ -19,30 +20,26 @@ import (
|
|||
)
|
||||
|
||||
type Handle struct {
|
||||
Index *IndexHandle
|
||||
Detail *DetailHandle
|
||||
C *gin.Context
|
||||
theme string
|
||||
Session sessions.Session
|
||||
ginH gin.H
|
||||
password string
|
||||
scene string
|
||||
Code int
|
||||
Stats string
|
||||
templ string
|
||||
components map[string]map[string][]Components[string]
|
||||
componentHook map[string][]func(Components[string]) (Components[string], bool)
|
||||
themeMods wpconfig.ThemeMods
|
||||
handlers map[string]map[string][]HandleCall
|
||||
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
|
||||
C *gin.Context
|
||||
theme string
|
||||
isInited bool
|
||||
Session sessions.Session
|
||||
ginH gin.H
|
||||
password string
|
||||
scene string
|
||||
Code int
|
||||
Stats string
|
||||
templ string
|
||||
themeMods wpconfig.ThemeMods
|
||||
err error
|
||||
abort bool
|
||||
stopPipe bool
|
||||
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 {
|
||||
return h.theme
|
||||
}
|
||||
|
@ -55,20 +52,20 @@ func (h *Handle) SetScene(scene string) {
|
|||
h.scene = scene
|
||||
}
|
||||
|
||||
func (h *Handle) Components() map[string]map[string][]Components[string] {
|
||||
return h.components
|
||||
func (h *Handle) Components() *safety.Map[string, map[string][]Components[string]] {
|
||||
return handleComponents
|
||||
}
|
||||
|
||||
func (h *Handle) ComponentHook() map[string][]func(Components[string]) (Components[string], bool) {
|
||||
return h.componentHook
|
||||
func (h *Handle) ComponentHook() *safety.Map[string, []func(Components[string]) (Components[string], bool)] {
|
||||
return handleComponentHook
|
||||
}
|
||||
|
||||
func (h *Handle) Handlers() map[string]map[string][]HandleCall {
|
||||
return h.handlers
|
||||
func (h *Handle) Handlers() *safety.Map[string, map[string][]HandleCall] {
|
||||
return handlerss
|
||||
}
|
||||
|
||||
func (h *Handle) HandleHook() map[string][]func(HandleCall) (HandleCall, bool) {
|
||||
return h.handleHook
|
||||
func (h *Handle) HandleHook() *safety.Map[string, []func(HandleCall) (HandleCall, bool)] {
|
||||
return handleHooks
|
||||
}
|
||||
|
||||
func (h *Handle) SetTemplate(template *template.Template) {
|
||||
|
@ -98,45 +95,48 @@ type HandleCall struct {
|
|||
Name string
|
||||
}
|
||||
|
||||
func InitHandle(fn func(*Handle), h *Handle) {
|
||||
var inited = false
|
||||
hh := reload.GetAnyValBys("themeArgAndConfig", h, func(h *Handle) (Handle, bool) {
|
||||
h.components = make(map[string]map[string][]Components[string])
|
||||
h.componentsArgs = make(map[string]any)
|
||||
h.componentFilterFn = make(map[string][]func(*Handle, string, ...any) string)
|
||||
h.handlers = make(map[string]map[string][]HandleCall)
|
||||
h.handleHook = make(map[string][]func(HandleCall) (HandleCall, bool))
|
||||
h.ginH = gin.H{}
|
||||
fnMap.Flush()
|
||||
fnHook.Flush()
|
||||
fn(h)
|
||||
v := apply.UsePlugins()
|
||||
pluginFn, ok := v.(func(*Handle))
|
||||
if ok {
|
||||
pluginFn(h)
|
||||
}
|
||||
h.C.Set("inited", true)
|
||||
inited = true
|
||||
return *h, true
|
||||
})
|
||||
func SetConfigHandle(a ...any) Handle {
|
||||
configFn := a[0].(func(*Handle))
|
||||
hh := a[1].(*Handle)
|
||||
h := &Handle{}
|
||||
mut := reload.GetGlobeMutex()
|
||||
mut.Lock()
|
||||
defer mut.Unlock()
|
||||
handleComponents.Flush()
|
||||
componentsArgs.Flush()
|
||||
handleComponentHook.Flush()
|
||||
componentFilterFns.Flush()
|
||||
handlerss.Flush()
|
||||
handleHooks.Flush()
|
||||
h.ginH = gin.H{}
|
||||
fnMap.Flush()
|
||||
fnHook.Flush()
|
||||
h.C = hh.C
|
||||
h.theme = hh.theme
|
||||
h.template = hh.template
|
||||
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["calPostClass"] = postClass(h)
|
||||
h.ginH["calBodyClass"] = bodyClass(h)
|
||||
h.ginH["customLogo"] = customLogo(h)
|
||||
if inited {
|
||||
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)
|
||||
h.isInited = true
|
||||
}
|
||||
|
||||
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 {
|
||||
ma = reload.FnVal(str.Join("paginationCache-", name, "-maxNum"), maxNum, nil)
|
||||
ma = reload.BuildFnVal(str.Join("paginationCache-", name, "-maxNum"), maxNum, 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)
|
||||
mapCache.Store(name, p)
|
||||
|
@ -215,7 +215,7 @@ func buildLockFn[K comparable](args ...any) cache.LockFn[K] {
|
|||
}
|
||||
loFn = helper.ParseArgs(loFn, args...)
|
||||
if name != "" {
|
||||
loFn = reload.FnVal(str.Join("cachesLocksNum-", name), num, loFn)
|
||||
loFn = reload.BuildFnVal(str.Join("cachesLocksNum-", name), num, loFn)
|
||||
}
|
||||
if lockFn == nil {
|
||||
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 == "" {
|
||||
return
|
||||
}
|
||||
fn := reload.FnVal(str.Join("cacheManger-", name, "-expiredTime"), expireTime, expireTimeFn)
|
||||
fn := reload.BuildFnVal(str.Join("cacheManger-", name, "-expiredTime"), expireTime, expireTimeFn)
|
||||
c.SetExpiredTime(fn)
|
||||
}
|
||||
|
||||
func ChangeExpireTime(t time.Duration, coverConf bool, name ...string) {
|
||||
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] {
|
||||
tFn = reload.FnVal(name, cycleTime, tFn)
|
||||
tFn = reload.BuildFnVal(name, cycleTime, tFn)
|
||||
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()
|
||||
batchFn = func(ctx context.Context, arr []string, a ...any) (map[string]string, error) {
|
||||
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
|
||||
}), nil
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ func TestMapCache_Flush(t *testing.T) {
|
|||
}
|
||||
ca := *NewMapCache[string, string](NewMemoryMapCache[string, string](func() time.Duration {
|
||||
return time.Second
|
||||
}), fn, nil)
|
||||
}), fn, nil, nil, nil)
|
||||
_, _ = ca.GetCache(ct, "aa", time.Second, ct, "aa")
|
||||
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
|
||||
}
|
||||
|
||||
var calls = safety.NewSlice(make([]queue, 0))
|
||||
var callsM = safety.NewMap[string, func()]()
|
||||
var mut = &sync.Mutex{}
|
||||
|
||||
var anyMap = safety.NewMap[string, any]()
|
||||
func GetGlobeMutex() *sync.Mutex {
|
||||
return mut
|
||||
}
|
||||
|
||||
type safetyVar[T, A any] struct {
|
||||
Val *safety.Var[val[T]]
|
||||
mutex sync.Mutex
|
||||
var waitReloadCalls = safety.NewSlice(make([]queue, 0))
|
||||
var callMap = safety.NewMap[string, func()]()
|
||||
|
||||
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 {
|
||||
v T
|
||||
ok bool
|
||||
counter number.Counter[int]
|
||||
type Val[T any] struct {
|
||||
V T
|
||||
Ok bool
|
||||
}
|
||||
type safetyMap[K comparable, V, A any] struct {
|
||||
val *safety.Map[K, V]
|
||||
mutex sync.Mutex
|
||||
type SafetyMap[K comparable, V, A any] struct {
|
||||
Val *safety.Map[K, V]
|
||||
Mutex sync.Mutex
|
||||
}
|
||||
|
||||
var safetyMaps = safety.NewMap[string, any]()
|
||||
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) {
|
||||
fn, ok := flushMapFn.Load(namespace)
|
||||
// GetValMap can get stored map value with namespace which called BuildSafetyMap, BuildMapFnWithConfirm, BuildMapFn, BuildMapFnWithAnyParams
|
||||
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 {
|
||||
return
|
||||
}
|
||||
|
@ -48,7 +63,7 @@ func FlushMapVal[T any](namespace string, key ...T) {
|
|||
|
||||
func FlushAnyVal(namespaces ...string) {
|
||||
for _, namespace := range namespaces {
|
||||
fn, ok := callsM.Load(namespace)
|
||||
fn, ok := callMap.Load(namespace)
|
||||
if !ok {
|
||||
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 {
|
||||
m := safetyMapFn[K, V, A](namespace)
|
||||
// BuildMapFnWithConfirm same as BuildMapFn
|
||||
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 {
|
||||
v, ok := m.val.Load(key)
|
||||
v, ok := m.Val.Load(key)
|
||||
if ok {
|
||||
return v
|
||||
}
|
||||
m.mutex.Lock()
|
||||
defer m.mutex.Unlock()
|
||||
v, ok = m.val.Load(key)
|
||||
m.Mutex.Lock()
|
||||
defer m.Mutex.Unlock()
|
||||
v, ok = m.Val.Load(key)
|
||||
if ok {
|
||||
return v
|
||||
}
|
||||
v, ok = fn(a)
|
||||
if ok {
|
||||
m.Val.Store(key, v)
|
||||
}
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
// BuildMapFn build given fn with a new fn which returned value can be saved and flushed when called Reload or FlushAnyVal
|
||||
// with namespace
|
||||
//
|
||||
// if give a float then can be reloaded early or lately, more bigger more earlier
|
||||
//
|
||||
// if give a bool false will not flushed when called Reload, then can called GetValMap to flush manually
|
||||
func BuildMapFn[K comparable, V, A any](namespace string, fn func(A) V, a ...any) func(key K, args A) V {
|
||||
m := BuildSafetyMap[K, V, A](namespace, a...)
|
||||
return func(key K, a A) V {
|
||||
v, ok := m.Val.Load(key)
|
||||
if ok {
|
||||
return v
|
||||
}
|
||||
m.Mutex.Lock()
|
||||
defer m.Mutex.Unlock()
|
||||
v, ok = m.Val.Load(key)
|
||||
if ok {
|
||||
return v
|
||||
}
|
||||
v = fn(a)
|
||||
m.val.Store(key, v)
|
||||
m.Val.Store(key, v)
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func safetyMapFn[K comparable, V, A any](namespace string, args ...any) *safetyMap[K, V, A] {
|
||||
vv, ok := safetyMaps.Load(namespace)
|
||||
var m *safetyMap[K, V, A]
|
||||
if ok {
|
||||
m = vv.(*safetyMap[K, V, A])
|
||||
} else {
|
||||
safetyMapLock.Lock()
|
||||
defer safetyMapLock.Unlock()
|
||||
vv, ok = safetyMaps.Load(namespace)
|
||||
// BuildMapFnWithAnyParams same as BuildMapFn use multiple params
|
||||
func BuildMapFnWithAnyParams[K comparable, V any](namespace string, fn func(...any) V, a ...any) func(key K, a ...any) V {
|
||||
m := BuildSafetyMap[K, V, any](namespace, a...)
|
||||
return func(key K, a ...any) V {
|
||||
v, ok := m.Val.Load(key)
|
||||
if ok {
|
||||
m = vv.(*safetyMap[K, V, A])
|
||||
} else {
|
||||
m = &safetyMap[K, V, A]{safety.NewMap[K, V](), sync.Mutex{}}
|
||||
ord, _ := parseArgs(args...)
|
||||
flushMapFn.Store(namespace, func(a any) {
|
||||
k, ok := a.([]K)
|
||||
if !ok && len(k) > 0 {
|
||||
return
|
||||
}
|
||||
for _, key := range k {
|
||||
m.val.Delete(key)
|
||||
}
|
||||
})
|
||||
Push(func() {
|
||||
m.val.Flush()
|
||||
}, ord, namespace)
|
||||
safetyMaps.Store(namespace, m)
|
||||
return v
|
||||
}
|
||||
m.Mutex.Lock()
|
||||
defer m.Mutex.Unlock()
|
||||
v, ok = m.Val.Load(key)
|
||||
if ok {
|
||||
return v
|
||||
}
|
||||
v = fn(a)
|
||||
m.Val.Store(key, v)
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func BuildSafetyMap[K comparable, V, A any](namespace string, args ...any) *SafetyMap[K, V, A] {
|
||||
vv, ok := safetyMaps.Load(namespace)
|
||||
var m *SafetyMap[K, V, A]
|
||||
if ok {
|
||||
m = vv.(*SafetyMap[K, V, A])
|
||||
return m
|
||||
}
|
||||
safetyMapLock.Lock()
|
||||
defer safetyMapLock.Unlock()
|
||||
vv, ok = safetyMaps.Load(namespace)
|
||||
if ok {
|
||||
m = vv.(*SafetyMap[K, V, A])
|
||||
return m
|
||||
}
|
||||
m = &SafetyMap[K, V, A]{safety.NewMap[K, V](), sync.Mutex{}}
|
||||
ord, _ := parseArgs(args...)
|
||||
autoFlush := helper.ParseArgs(true, args...)
|
||||
deleteMapFn.Store(namespace, func(a any) {
|
||||
k, ok := a.([]K)
|
||||
if !ok && len(k) > 0 {
|
||||
return
|
||||
}
|
||||
for _, key := range k {
|
||||
m.Val.Delete(key)
|
||||
}
|
||||
})
|
||||
if autoFlush {
|
||||
Push(func() {
|
||||
m.Val.Flush()
|
||||
}, ord, namespace)
|
||||
}
|
||||
safetyMaps.Store(namespace, m)
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
func GetAnyValMapBy[K comparable, V, A any](namespace string, key K, a A, fn func(A) (V, bool), args ...any) V {
|
||||
m := safetyMapFn[K, V, A](namespace, args...)
|
||||
v, ok := m.val.Load(key)
|
||||
m := BuildSafetyMap[K, V, A](namespace, args...)
|
||||
v, ok := m.Val.Load(key)
|
||||
if ok {
|
||||
return v
|
||||
}
|
||||
m.mutex.Lock()
|
||||
defer m.mutex.Unlock()
|
||||
v, ok = m.val.Load(key)
|
||||
m.Mutex.Lock()
|
||||
defer m.Mutex.Unlock()
|
||||
v, ok = m.Val.Load(key)
|
||||
if ok {
|
||||
return v
|
||||
}
|
||||
v, ok = fn(a)
|
||||
if ok {
|
||||
m.val.Store(key, v)
|
||||
m.Val.Store(key, v)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func anyVal[T, A any](namespace string, counter bool, args ...any) *safetyVar[T, A] {
|
||||
var vv *safetyVar[T, A]
|
||||
func BuildAnyVal[T, A any](namespace string, counter bool, args ...any) *SafetyVar[T, A] {
|
||||
var vv *SafetyVar[T, A]
|
||||
vvv, ok := safetyMaps.Load(namespace)
|
||||
if ok {
|
||||
vv = vvv.(*safetyVar[T, A])
|
||||
vv = vvv.(*SafetyVar[T, A])
|
||||
} else {
|
||||
safetyMapLock.Lock()
|
||||
defer safetyMapLock.Unlock()
|
||||
vvv, ok = safetyMaps.Load(namespace)
|
||||
if ok {
|
||||
vv = vvv.(*safetyVar[T, A])
|
||||
vv = vvv.(*SafetyVar[T, A])
|
||||
} else {
|
||||
v := val[T]{}
|
||||
if counter {
|
||||
v.counter = number.Counters[int]()
|
||||
}
|
||||
vv = &safetyVar[T, A]{safety.NewVar(v), sync.Mutex{}}
|
||||
v := Val[T]{}
|
||||
vv = &SafetyVar[T, A]{safety.NewVar(v), sync.Mutex{}}
|
||||
ord, _ := parseArgs(args...)
|
||||
Push(func() {
|
||||
vv.Val.Flush()
|
||||
|
@ -153,53 +217,117 @@ func anyVal[T, A any](namespace string, counter bool, args ...any) *safetyVar[T,
|
|||
return vv
|
||||
}
|
||||
|
||||
func GetAnyValBy[T, A any](namespace string, a A, fn func(A) (T, bool), args ...any) T {
|
||||
var vv = anyVal[T, A](namespace, true, args...)
|
||||
var ok bool
|
||||
func GetAnyValBys[T, A any](namespace string, a A, fn func(A) (T, bool), args ...any) T {
|
||||
var vv = BuildAnyVal[T, A](namespace, false, args...)
|
||||
v := vv.Val.Load()
|
||||
if v.ok {
|
||||
return v.v
|
||||
if v.Ok {
|
||||
return v.V
|
||||
}
|
||||
vv.mutex.Lock()
|
||||
defer vv.mutex.Unlock()
|
||||
vv.Mutex.Lock()
|
||||
defer vv.Mutex.Unlock()
|
||||
v = vv.Val.Load()
|
||||
if v.ok {
|
||||
return v.v
|
||||
if v.Ok {
|
||||
return v.V
|
||||
}
|
||||
v.v, ok = fn(a)
|
||||
if v.counter == nil {
|
||||
v.counter = number.Counters[int]()
|
||||
}
|
||||
times := v.counter()
|
||||
tryTimes := helper.ParseArgs(1, args...)
|
||||
if ok || times >= tryTimes {
|
||||
v.ok = true
|
||||
vv.Val.Store(v)
|
||||
}
|
||||
return v.v
|
||||
v.V, v.Ok = fn(a)
|
||||
vv.Val.Store(v)
|
||||
return v.V
|
||||
}
|
||||
|
||||
func GetAnyValBys[T, A any](namespace string, a A, fn func(A) (T, bool), args ...any) T {
|
||||
var vv = anyVal[T, A](namespace, false, args...)
|
||||
v := vv.Val.Load()
|
||||
if v.ok {
|
||||
return v.v
|
||||
// BuildValFnWithConfirm same as BuildValFn
|
||||
//
|
||||
// if give a int and value bigger than 1 will be a times which built fn called return false
|
||||
func BuildValFnWithConfirm[T, A any](namespace string, fn func(A) (T, bool), args ...any) func(A) T {
|
||||
var vv = BuildAnyVal[T, A](namespace, false, args...)
|
||||
tryTimes := helper.ParseArgs(1, args...)
|
||||
var counter func() int
|
||||
if tryTimes > 1 {
|
||||
counter = number.Counters[int]()
|
||||
}
|
||||
vv.mutex.Lock()
|
||||
defer vv.mutex.Unlock()
|
||||
v = vv.Val.Load()
|
||||
if v.ok {
|
||||
return v.v
|
||||
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, 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
|
||||
//
|
||||
// args same as Push
|
||||
//
|
||||
// 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] {
|
||||
ss := safety.NewVar(defaults)
|
||||
ord, name := parseArgs(args...)
|
||||
|
@ -261,37 +389,42 @@ func SafeMap[K comparable, T any](args ...any) *safety.Map[K, T] {
|
|||
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) {
|
||||
ord, name := parseArgs(a...)
|
||||
calls.Append(queue{fn, ord, name})
|
||||
waitReloadCalls.Append(queue{fn, ord, name})
|
||||
if name != "" {
|
||||
callsM.Store(name, fn)
|
||||
callMap.Store(name, fn)
|
||||
}
|
||||
}
|
||||
|
||||
func Reload() {
|
||||
callsM.Flush()
|
||||
flushMapFn.Flush()
|
||||
callll := calls.Load()
|
||||
slice.SimpleSort(callll, slice.DESC, func(t queue) float64 {
|
||||
mut.Lock()
|
||||
defer mut.Unlock()
|
||||
callMap.Flush()
|
||||
deleteMapFn.Flush()
|
||||
reloadCalls := waitReloadCalls.Load()
|
||||
slice.SimpleSort(reloadCalls, slice.DESC, func(t queue) float64 {
|
||||
return t.order
|
||||
})
|
||||
for _, call := range callll {
|
||||
for _, call := range reloadCalls {
|
||||
call.fn()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type Any[T any] struct {
|
||||
fn func() T
|
||||
v *safety.Var[T]
|
||||
isUseManger *safety.Var[bool]
|
||||
fn func() T
|
||||
v *safety.Var[T]
|
||||
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 {
|
||||
fn = func() T {
|
||||
return t
|
||||
|
@ -301,23 +434,23 @@ func FnVal[T any](name string, t T, fn func() T) func() T {
|
|||
}
|
||||
p := safety.NewVar(t)
|
||||
e := Any[T]{
|
||||
fn: fn,
|
||||
v: p,
|
||||
isUseManger: safety.NewVar(false),
|
||||
fn: fn,
|
||||
v: p,
|
||||
isManual: safety.NewVar(false),
|
||||
}
|
||||
Push(func() {
|
||||
if !e.isUseManger.Load() {
|
||||
if !e.isManual.Load() {
|
||||
e.v.Store(fn())
|
||||
}
|
||||
})
|
||||
anyMap.Store(name, e)
|
||||
setFnVal.Store(name, e)
|
||||
return func() T {
|
||||
return e.v.Load()
|
||||
}
|
||||
}
|
||||
|
||||
func ChangeFnVal[T any](name string, val T, coverConf bool) {
|
||||
v, ok := anyMap.Load(name)
|
||||
func SetFnVal[T any](name string, val T, onlyManual bool) {
|
||||
v, ok := setFnVal.Load(name)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
@ -325,8 +458,8 @@ func ChangeFnVal[T any](name string, val T, coverConf bool) {
|
|||
if !ok {
|
||||
return
|
||||
}
|
||||
if coverConf && !vv.isUseManger.Load() {
|
||||
vv.isUseManger.Store(true)
|
||||
if onlyManual && !vv.isManual.Load() {
|
||||
vv.isManual.Store(true)
|
||||
}
|
||||
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
|
||||
})
|
||||
fmt.Println(v)
|
||||
FlushMapVal("key", 2)
|
||||
DeleteMapVal("key", 2)
|
||||
|
||||
v = GetAnyValMapBy("key", 2, struct{}{}, func(a struct{}) (int, bool) {
|
||||
fmt.Println("xxxxx")
|
||||
|
@ -32,15 +32,15 @@ func TestFlushMapVal(t *testing.T) {
|
|||
func TestGetAnyMapFnBys(t *testing.T) {
|
||||
var i int
|
||||
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++
|
||||
return a + 1
|
||||
return a + 1, true
|
||||
})
|
||||
vv := v(1, 2)
|
||||
vvv := v(2, 3)
|
||||
fmt.Println(vv, vvv)
|
||||
v(1, 2)
|
||||
FlushMapVal("name", 2)
|
||||
DeleteMapVal("name", 2)
|
||||
v(2, 3)
|
||||
fmt.Println(i)
|
||||
})
|
||||
|
|
|
@ -192,8 +192,8 @@ func WithDefaultVal[K comparable, V any](m map[K]V, k K, defaults V) V {
|
|||
return defaults
|
||||
}
|
||||
|
||||
func AnyAnyMap[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)
|
||||
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)
|
||||
for k, v := range m {
|
||||
key, val, ok := fn(k, v)
|
||||
if ok {
|
||||
|
|
|
@ -172,10 +172,10 @@ func Slice[T any](arr []T, offset, length int) (r []T) {
|
|||
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)
|
||||
for _, t := range arr {
|
||||
k, v, ok := fn(t)
|
||||
for i, t := range arr {
|
||||
k, v, ok := fn(t, i)
|
||||
if ok {
|
||||
r[k] = v
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user