Compare commits
No commits in common. "e7ea2bf3349e73a14add8357b6775f3a20b284d5" and "00c16c03a4b3c8dade4da820364cf32baa4e1aa7" have entirely different histories.
e7ea2bf334
...
00c16c03a4
@ -192,20 +192,3 @@ func RenderedHtml(t *template.Template, data map[string]any) (r string, err erro
|
|||||||
r = buf.String()
|
r = buf.String()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func BuildOptions[T any, K comparable](a []T, selected K, fn func(T) (K, any), attr ...string) string {
|
|
||||||
s := strings2.NewBuilder()
|
|
||||||
att := ""
|
|
||||||
if len(attr) > 0 {
|
|
||||||
att = strings.Join(attr, " ")
|
|
||||||
}
|
|
||||||
for _, t := range a {
|
|
||||||
k, v := fn(t)
|
|
||||||
ss := ""
|
|
||||||
if k == selected {
|
|
||||||
ss = "selected"
|
|
||||||
}
|
|
||||||
s.Sprintf(`<option %s %s value="%v">%v</option>`, ss, att, v, k)
|
|
||||||
}
|
|
||||||
return s.String()
|
|
||||||
}
|
|
||||||
|
@ -91,13 +91,3 @@ func Divide[T constraints.Integer | constraints.Float](i, j T) T {
|
|||||||
func CalTotalPage[T constraints.Integer](totalRows, size T) T {
|
func CalTotalPage[T constraints.Integer](totalRows, size T) T {
|
||||||
return T(math.Ceil(float64(totalRows) / float64(size)))
|
return T(math.Ceil(float64(totalRows) / float64(size)))
|
||||||
}
|
}
|
||||||
|
|
||||||
type Counter[T constraints.Integer] func() T
|
|
||||||
|
|
||||||
func Counters[T constraints.Integer]() func() T {
|
|
||||||
var count T
|
|
||||||
return func() T {
|
|
||||||
count++
|
|
||||||
return count
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -2,7 +2,6 @@ package number
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/fthvgb1/wp-go/taskPools"
|
|
||||||
"golang.org/x/exp/constraints"
|
"golang.org/x/exp/constraints"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
@ -251,40 +250,3 @@ func TestCalTotalPage(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCounters(t *testing.T) {
|
|
||||||
type testCase[T constraints.Integer] struct {
|
|
||||||
name string
|
|
||||||
want func() T
|
|
||||||
}
|
|
||||||
var c = 0
|
|
||||||
tests := []testCase[int]{
|
|
||||||
{
|
|
||||||
name: "t1",
|
|
||||||
want: func() int {
|
|
||||||
c++
|
|
||||||
return c
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
got := Counters[int]()
|
|
||||||
if !reflect.DeepEqual(got(), tt.want()) {
|
|
||||||
t.Errorf("Counters() = %v, want %v", got(), tt.want())
|
|
||||||
}
|
|
||||||
got()
|
|
||||||
got()
|
|
||||||
got()
|
|
||||||
p := taskPools.NewPools(6)
|
|
||||||
for i := 0; i < 50; i++ {
|
|
||||||
p.Execute(func() {
|
|
||||||
got()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
p.Wait()
|
|
||||||
fmt.Println("got ", got())
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
34
internal/pkg/cache/cache.go
vendored
34
internal/pkg/cache/cache.go
vendored
@ -3,9 +3,11 @@ package cache
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"github.com/fthvgb1/wp-go/cache"
|
"github.com/fthvgb1/wp-go/cache"
|
||||||
|
"github.com/fthvgb1/wp-go/helper"
|
||||||
"github.com/fthvgb1/wp-go/helper/slice"
|
"github.com/fthvgb1/wp-go/helper/slice"
|
||||||
"github.com/fthvgb1/wp-go/internal/cmd/cachemanager"
|
"github.com/fthvgb1/wp-go/internal/cmd/cachemanager"
|
||||||
"github.com/fthvgb1/wp-go/internal/pkg/config"
|
"github.com/fthvgb1/wp-go/internal/pkg/config"
|
||||||
|
"github.com/fthvgb1/wp-go/internal/pkg/constraints"
|
||||||
"github.com/fthvgb1/wp-go/internal/pkg/dao"
|
"github.com/fthvgb1/wp-go/internal/pkg/dao"
|
||||||
"github.com/fthvgb1/wp-go/internal/pkg/logs"
|
"github.com/fthvgb1/wp-go/internal/pkg/logs"
|
||||||
"github.com/fthvgb1/wp-go/internal/pkg/models"
|
"github.com/fthvgb1/wp-go/internal/pkg/models"
|
||||||
@ -15,7 +17,7 @@ import (
|
|||||||
|
|
||||||
var postContextCache *cache.MapCache[uint64, dao.PostContext]
|
var postContextCache *cache.MapCache[uint64, dao.PostContext]
|
||||||
var archivesCaches *Arch
|
var archivesCaches *Arch
|
||||||
var categoryAndTagsCaches *cache.MapCache[int, []models.TermsMy]
|
var categoryAndTagsCaches *cache.VarCache[[]models.TermsMy]
|
||||||
var recentPostsCaches *cache.VarCache[[]models.Posts]
|
var recentPostsCaches *cache.VarCache[[]models.Posts]
|
||||||
var recentCommentsCaches *cache.VarCache[[]models.Comments]
|
var recentCommentsCaches *cache.VarCache[[]models.Comments]
|
||||||
var postCommentCaches *cache.MapCache[uint64, []uint64]
|
var postCommentCaches *cache.MapCache[uint64, []uint64]
|
||||||
@ -63,7 +65,7 @@ func InitActionsCommonCache() {
|
|||||||
|
|
||||||
postMetaCache = cachemanager.MapBatchCacheBy(dao.GetPostMetaByPostIds, c.CacheTime.PostDataCacheTime)
|
postMetaCache = cachemanager.MapBatchCacheBy(dao.GetPostMetaByPostIds, c.CacheTime.PostDataCacheTime)
|
||||||
|
|
||||||
categoryAndTagsCaches = cachemanager.MapCacheBy[int](dao.CategoriesAndTags, c.CacheTime.CategoryCacheTime)
|
categoryAndTagsCaches = cache.NewVarCache(dao.CategoriesAndTags, c.CacheTime.CategoryCacheTime)
|
||||||
|
|
||||||
recentPostsCaches = cache.NewVarCache(dao.RecentPosts, c.CacheTime.RecentPostCacheTime)
|
recentPostsCaches = cache.NewVarCache(dao.RecentPosts, c.CacheTime.RecentPostCacheTime)
|
||||||
|
|
||||||
@ -126,22 +128,22 @@ func (a *Arch) getArchiveCache(ctx context.Context) []models.PostArchive {
|
|||||||
//
|
//
|
||||||
// t is constraints.Tag or constraints.Category
|
// t is constraints.Tag or constraints.Category
|
||||||
func CategoriesTags(ctx context.Context, t ...int) []models.TermsMy {
|
func CategoriesTags(ctx context.Context, t ...int) []models.TermsMy {
|
||||||
tt := 0
|
r, err := categoryAndTagsCaches.GetCache(ctx, time.Second, ctx)
|
||||||
if len(t) > 0 {
|
|
||||||
tt = t[0]
|
|
||||||
}
|
|
||||||
r, err := categoryAndTagsCaches.GetCache(ctx, tt, time.Second, ctx, tt)
|
|
||||||
logs.ErrPrintln(err, "get category err")
|
logs.ErrPrintln(err, "get category err")
|
||||||
|
if len(t) > 0 {
|
||||||
|
return slice.Filter(r, func(my models.TermsMy, i int) bool {
|
||||||
|
return helper.Or(t[0] == constraints.Tag, "post_tag", "category") == my.Taxonomy
|
||||||
|
})
|
||||||
|
}
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
func AllCategoryTagsNames(ctx context.Context, t ...int) map[string]struct{} {
|
func AllCategoryTagsNames(ctx context.Context, c int) map[string]struct{} {
|
||||||
tt := 0
|
r, err := categoryAndTagsCaches.GetCache(ctx, time.Second, ctx)
|
||||||
if len(t) > 0 {
|
|
||||||
tt = t[0]
|
|
||||||
}
|
|
||||||
r, err := categoryAndTagsCaches.GetCache(ctx, tt, time.Second, ctx, tt)
|
|
||||||
logs.ErrPrintln(err, "get category err")
|
logs.ErrPrintln(err, "get category err")
|
||||||
return slice.ToMap(r, func(t models.TermsMy) (string, struct{}) {
|
return slice.FilterAndToMap(r, func(t models.TermsMy) (string, struct{}, bool) {
|
||||||
return t.Name, struct{}{}
|
if helper.Or(c == constraints.Tag, "post_tag", "category") == t.Taxonomy {
|
||||||
}, true)
|
return t.Name, struct{}{}, true
|
||||||
|
}
|
||||||
|
return "", struct{}{}, false
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ package dao
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"github.com/fthvgb1/wp-go/internal/pkg/constraints"
|
|
||||||
"github.com/fthvgb1/wp-go/internal/pkg/models"
|
"github.com/fthvgb1/wp-go/internal/pkg/models"
|
||||||
"github.com/fthvgb1/wp-go/internal/wpconfig"
|
"github.com/fthvgb1/wp-go/internal/wpconfig"
|
||||||
"github.com/fthvgb1/wp-go/model"
|
"github.com/fthvgb1/wp-go/model"
|
||||||
@ -22,16 +21,7 @@ type PostContext struct {
|
|||||||
|
|
||||||
func CategoriesAndTags(a ...any) (terms []models.TermsMy, err error) {
|
func CategoriesAndTags(a ...any) (terms []models.TermsMy, err error) {
|
||||||
ctx := a[0].(context.Context)
|
ctx := a[0].(context.Context)
|
||||||
t, ok := a[1].(int)
|
|
||||||
var in = []any{"category", "post_tag"}
|
var in = []any{"category", "post_tag"}
|
||||||
if ok {
|
|
||||||
switch t {
|
|
||||||
case constraints.Category:
|
|
||||||
in = []any{"category"}
|
|
||||||
case constraints.Tag:
|
|
||||||
in = []any{"post_tag"}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
terms, err = model.Finds[models.TermsMy](ctx, model.Conditions(
|
terms, err = model.Finds[models.TermsMy](ctx, model.Conditions(
|
||||||
model.Where(model.SqlBuilder{
|
model.Where(model.SqlBuilder{
|
||||||
{"tt.count", ">", "0", "int"},
|
{"tt.count", ">", "0", "int"},
|
||||||
|
@ -177,15 +177,10 @@ func MonthPost(args ...any) (r []uint64, err error) {
|
|||||||
{"year(post_date)", year},
|
{"year(post_date)", year},
|
||||||
{"month(post_date)", month},
|
{"month(post_date)", month},
|
||||||
}
|
}
|
||||||
r, err = model.Column[models.Posts, uint64](ctx, func(v models.Posts) (uint64, bool) {
|
return model.Column[models.Posts, uint64](ctx, func(v models.Posts) (uint64, bool) {
|
||||||
return v.Id, true
|
return v.Id, true
|
||||||
}, model.Conditions(
|
}, model.Conditions(
|
||||||
model.Fields("ID"),
|
model.Fields("ID"),
|
||||||
model.Where(where),
|
model.Where(where),
|
||||||
))
|
))
|
||||||
l := int64(len(r))
|
|
||||||
if l > atomic.LoadInt64(&TotalRaw) {
|
|
||||||
atomic.StoreInt64(&TotalRaw, l)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
71
internal/theme/wp/components/block.go
Normal file
71
internal/theme/wp/components/block.go
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
package components
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/dlclark/regexp2"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Block struct {
|
||||||
|
Closer string
|
||||||
|
NameSpace string
|
||||||
|
Name string
|
||||||
|
Attrs string
|
||||||
|
Void string
|
||||||
|
Len int
|
||||||
|
StartOffset int
|
||||||
|
}
|
||||||
|
|
||||||
|
var block = regexp2.MustCompile(`<!--\s+(?<closer>/)?wp:(?<namespace>[a-z][a-z0-9_-]*\/)?(?<name>[a-z][a-z0-9_-]*)\s+(?<attrs>{(?:(?:[^}]+|}+(?=})|(?!}\s+\/?-->).)*)?}\s+)?(?<void>\/)?-->`, regexp2.IgnoreCase|regexp2.Singleline)
|
||||||
|
|
||||||
|
func ParseBlock(s string) []Block {
|
||||||
|
m, err := block.FindStringMatch(s)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
var blocks []Block
|
||||||
|
for m != nil {
|
||||||
|
if m.GroupCount() < 1 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
b, _ := token(m.Groups())
|
||||||
|
b.StartOffset = m.Group.Index
|
||||||
|
b.Len = m.Length
|
||||||
|
blocks = append(blocks, b)
|
||||||
|
m, _ = block.FindNextMatch(m)
|
||||||
|
}
|
||||||
|
return blocks
|
||||||
|
}
|
||||||
|
|
||||||
|
func token(g []regexp2.Group) (Block, string) {
|
||||||
|
if len(g) < 1 {
|
||||||
|
return Block{}, "no-more-tokens"
|
||||||
|
}
|
||||||
|
b := Block{NameSpace: "core/"}
|
||||||
|
for i, group := range g {
|
||||||
|
v := group.String()
|
||||||
|
if v == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
switch i {
|
||||||
|
case 1:
|
||||||
|
b.Closer = v
|
||||||
|
case 2:
|
||||||
|
b.NameSpace = v
|
||||||
|
case 3:
|
||||||
|
b.Name = v
|
||||||
|
case 4:
|
||||||
|
b.Attrs = v
|
||||||
|
case 5:
|
||||||
|
b.Void = v
|
||||||
|
default:
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if b.Void != "" {
|
||||||
|
return b, ""
|
||||||
|
}
|
||||||
|
if b.Closer != "" {
|
||||||
|
return b, "block-closer"
|
||||||
|
}
|
||||||
|
return b, "block-opener"
|
||||||
|
}
|
@ -144,17 +144,15 @@ func categoryLi(root *tree.Node[models.TermsMy, uint64], cate, roots *tree.Node[
|
|||||||
}
|
}
|
||||||
s.Sprintf(` <li class="cat-item cat-item-%d %s">
|
s.Sprintf(` <li class="cat-item cat-item-%d %s">
|
||||||
<a %s href="/p/category/%s">%s %s</a>
|
<a %s href="/p/category/%s">%s %s</a>
|
||||||
|
</li>
|
||||||
`, category.Terms.TermId, strings.Join(class, " "), aria, category.Name, category.Name, count)
|
`, category.Terms.TermId, strings.Join(class, " "), aria, category.Name, category.Name, count)
|
||||||
|
|
||||||
if len(*child.Children) > 0 {
|
if len(*child.Children) > 0 {
|
||||||
s.WriteString(` <ul class="children">
|
s.WriteString(`<ul class="children">
|
||||||
`)
|
`)
|
||||||
categoryLi(&child, cate, roots, isCount, s)
|
categoryLi(&child, cate, roots, isCount, s)
|
||||||
s.WriteString(`</ul>
|
s.WriteString(`</ul>`)
|
||||||
`)
|
|
||||||
}
|
}
|
||||||
s.Sprintf(`</li>`)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var widgetFn = map[string]wp.Components[string]{
|
var widgetFn = map[string]wp.Components[string]{
|
||||||
"search": {Fn: widget.Search},
|
"search": {Fn: widget.Search, CacheKey: "widgetSearch"},
|
||||||
"recent-posts": {Fn: widget.RecentPosts},
|
"recent-posts": {Fn: widget.RecentPosts},
|
||||||
"recent-comments": {Fn: widget.RecentComments},
|
"recent-comments": {Fn: widget.RecentComments},
|
||||||
"archives": {Fn: widget.Archive},
|
"archives": {Fn: widget.Archive},
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
package safety
|
|
||||||
|
|
||||||
import (
|
|
||||||
"golang.org/x/exp/constraints"
|
|
||||||
"sync/atomic"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Counter[T constraints.Integer]() func() T {
|
|
||||||
var counter int64
|
|
||||||
return func() T {
|
|
||||||
return T(atomic.AddInt64(&counter, 1))
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user