diff --git a/helper/maps/map.go b/helper/maps/map.go index 9ec3ae2..5fe48c8 100644 --- a/helper/maps/map.go +++ b/helper/maps/map.go @@ -48,3 +48,10 @@ func AnyAnyToStrAny(m map[any]any) (r map[string]any) { } return } + +func Reduce[T, V any, K comparable](m map[K]V, fn func(K, V, T) T, r T) T { + for k, v := range m { + r = fn(k, v, r) + } + return r +} diff --git a/helper/slice/set.go b/helper/slice/set.go index 8963d80..c3b6972 100644 --- a/helper/slice/set.go +++ b/helper/slice/set.go @@ -53,6 +53,23 @@ func DiffByFn[T any](a []T, fn func(i, j T) bool, b ...[]T) (r []T) { return } +func DiffNewByFn[T, V any](a []T, fn func(i, j T) bool, fnV func(T) V, b ...[]T) (r []V) { + for _, t := range a { + f := false + for _, ts := range b { + if IsContainedByFn(ts, t, fn) { + f = true + break + } + } + if f { + continue + } + r = append(r, fnV(t)) + } + return +} + func Intersect[T comparable](a []T, b ...[]T) (r []T) { for _, t := range a { f := false @@ -87,6 +104,23 @@ func IntersectByFn[T any](a []T, fn func(i, j T) bool, b ...[]T) (r []T) { return } +func IntersectNewByFn[T, V any](a []T, fn func(i, j T) bool, fnV func(T) V, b ...[]T) (r []V) { + for _, t := range a { + f := false + for _, ts := range b { + if !IsContainedByFn(ts, t, fn) { + f = true + break + } + } + if f { + continue + } + r = append(r, fnV(t)) + } + return +} + func Unique[T comparable](a ...[]T) (r []T) { m := map[T]struct{}{} for _, ts := range a { @@ -112,3 +146,15 @@ func UniqueByFn[T any](fn func(T, T) bool, a ...[]T) (r []T) { } return r } +func UniqueNewByFn[T, V any](fn func(T, T) bool, fnVal func(T) V, a ...[]T) (r []V) { + var rr []T + for _, ts := range a { + for _, t := range ts { + if !IsContainedByFn(rr, t, fn) { + rr = append(rr, t) + r = append(r, fnVal(t)) + } + } + } + return r +} diff --git a/helper/slice/set_test.go b/helper/slice/set_test.go index a0ad576..b4c7f06 100644 --- a/helper/slice/set_test.go +++ b/helper/slice/set_test.go @@ -83,6 +83,46 @@ func TestDiffByFn(t *testing.T) { } } +func TestDiffNewByFn(t *testing.T) { + type args[T x, V int] struct { + a []T + fn func(i, j T) bool + fnV func(T) V + b [][]T + } + type testCase[T x, V int] struct { + name string + args args[T, V] + wantR []V + } + tests := []testCase[x, int]{ + { + name: "t1", + args: args[x, int]{ + a: y(number.Range(1, 10, 1)), + fn: func(i, j x) bool { + return i.int == j.int + }, + fnV: func(v x) int { + return v.int + }, + b: [][]x{ + y(number.Range(3, 7, 1)), + y(number.Range(6, 9, 1)), + }, + }, + wantR: []int{1, 2, 10}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if gotR := DiffNewByFn(tt.args.a, tt.args.fn, tt.args.fnV, tt.args.b...); !reflect.DeepEqual(gotR, tt.wantR) { + t.Errorf("DiffNewByFn() = %v, want %v", gotR, tt.wantR) + } + }) + } +} + func TestIntersect(t *testing.T) { type args[T int] struct { a []T @@ -148,6 +188,46 @@ func TestIntersectByFn(t *testing.T) { } } +func TestIntersectNewByFn(t *testing.T) { + type args[T x, V int] struct { + a []T + fn func(i, j T) bool + fnV func(T) V + b [][]T + } + type testCase[T x, V int] struct { + name string + args args[T, V] + wantR []V + } + tests := []testCase[x, int]{ + { + name: "t1", + args: args[x, int]{ + a: y(number.Range(1, 10, 1)), + fn: func(i, j x) bool { + return i.int == j.int + }, + fnV: func(v x) int { + return v.int + }, + b: [][]x{ + y(number.Range(3, 7, 1)), + y(number.Range(6, 9, 1)), + }, + }, + wantR: []int{6, 7}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if gotR := IntersectNewByFn(tt.args.a, tt.args.fn, tt.args.fnV, tt.args.b...); !reflect.DeepEqual(gotR, tt.wantR) { + t.Errorf("IntersectNewByFn() = %v, want %v", gotR, tt.wantR) + } + }) + } +} + func TestUnique(t *testing.T) { type args[T int] struct { a [][]T @@ -169,6 +249,15 @@ func TestUnique(t *testing.T) { }, wantR: number.Range(1, 15, 1), }, + { + name: "t2", + args: args[int]{ + a: [][]int{ + {1, 1, 1, 2, 2, 2, 3, 3, 4, 5}, + }, + }, + wantR: number.Range(1, 5, 1), + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -209,3 +298,38 @@ func TestUniqueByFn(t *testing.T) { }) } } + +func TestUniqueNewByFn(t *testing.T) { + type args[T x, V int] struct { + fn func(T, T) bool + fnVal func(T) V + a [][]T + } + type testCase[T x, V int] struct { + name string + args args[T, V] + wantR []V + } + tests := []testCase[x, int]{ + { + name: "t1", + args: args[x, int]{ + fn: func(i, j x) bool { + return i.int == j.int + }, + fnVal: func(i x) int { + return i.int + }, + a: [][]x{y([]int{1, 1, 2, 2, 3, 3}), y([]int{2, 2, 4, 4})}, + }, + wantR: []int{1, 2, 3, 4}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if gotR := UniqueNewByFn(tt.args.fn, tt.args.fnVal, tt.args.a...); !reflect.DeepEqual(gotR, tt.wantR) { + t.Errorf("UniqueNewByFn() = %v, want %v", gotR, tt.wantR) + } + }) + } +} diff --git a/internal/actions/detail.go b/internal/actions/detail.go index dafa759..7d1a863 100644 --- a/internal/actions/detail.go +++ b/internal/actions/detail.go @@ -108,6 +108,7 @@ func Detail(c *gin.Context) { ginH["comments"] = hh.formatComment(commentss, 1, d) ginH["next"] = next ginH["user"] = user + ginH["scene"] = plugins.Detail } type Comment struct { diff --git a/internal/actions/index.go b/internal/actions/index.go index b7c82b6..87aa0b1 100644 --- a/internal/actions/index.go +++ b/internal/actions/index.go @@ -312,5 +312,6 @@ func Index(c *gin.Context) { ginH["totalPage"] = h.getTotalPage(totalRaw) ginH["currentPage"] = h.page ginH["title"] = h.getTitle() + ginH["scene"] = h.scene ginH["pagination"] = pagination.NewParsePagination(totalRaw, h.pageSize, h.page, h.paginationStep, q, c.Request.URL.Path) } diff --git a/internal/pkg/dao/postmeta.go b/internal/pkg/dao/postmeta.go index a8758ff..ec92134 100644 --- a/internal/pkg/dao/postmeta.go +++ b/internal/pkg/dao/postmeta.go @@ -2,14 +2,12 @@ package dao import ( "context" - "fmt" - "github.com/fthvgb1/wp-go/helper/maps" "github.com/fthvgb1/wp-go/helper/slice" "github.com/fthvgb1/wp-go/internal/pkg/logs" "github.com/fthvgb1/wp-go/internal/pkg/models" + "github.com/fthvgb1/wp-go/internal/plugins" "github.com/fthvgb1/wp-go/model" "strconv" - "strings" ) func GetPostMetaByPostIds(args ...any) (r map[uint64]map[string]any, err error) { @@ -64,35 +62,9 @@ func ToPostThumb(c context.Context, meta map[string]any, host string) (r models. if ok { metadata, ok := x.(models.WpAttachmentMetadata) if ok { - r = thumbnail(metadata, "post-thumbnail", host) + r = plugins.Thumbnail(metadata, "post-thumbnail", host, "thumbnail") } } } return } - -func thumbnail(metadata models.WpAttachmentMetadata, thumbType, host string) (r models.PostThumbnail) { - if _, ok := metadata.Sizes[thumbType]; ok { - r.Path = fmt.Sprintf("%s/wp-content/uploads/%s", host, metadata.File) - r.Width = metadata.Sizes[thumbType].Width - r.Height = metadata.Sizes[thumbType].Height - up := strings.Split(metadata.File, "/") - r.Srcset = strings.Join(maps.FilterToSlice[string](metadata.Sizes, func(s string, size models.MetaDataFileSize) (r string, ok bool) { - up[2] = size.File - if s == "post-thumbnail" { - return - } - r = fmt.Sprintf("%s/wp-content/uploads/%s %dw", host, strings.Join(up, "/"), size.Width) - ok = true - return - }), ", ") - r.Sizes = fmt.Sprintf("(max-width: %dpx) 100vw, %dpx", r.Width, r.Width) - if r.Width >= 740 && r.Width < 767 { - r.Sizes = "(max-width: 706px) 89vw, (max-width: 767px) 82vw, 740px" - } else if r.Width >= 767 { - r.Sizes = "(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px" - } - r.OriginAttachmentData = metadata - } - return -} diff --git a/internal/pkg/dao/posts.go b/internal/pkg/dao/posts.go index 089c586..92a4e4f 100644 --- a/internal/pkg/dao/posts.go +++ b/internal/pkg/dao/posts.go @@ -6,6 +6,7 @@ import ( "fmt" "github.com/fthvgb1/wp-go/helper/slice" "github.com/fthvgb1/wp-go/internal/pkg/models" + "github.com/fthvgb1/wp-go/internal/plugins" "github.com/fthvgb1/wp-go/internal/wpconfig" "github.com/fthvgb1/wp-go/model" "strings" @@ -68,7 +69,7 @@ func GetPostsByIds(ids ...any) (m map[uint64]models.Posts, err error) { pp.Thumbnail = thumb } } else if pp.PostType == "attachment" && pp.AttachmentMetadata.File != "" { - thumb := thumbnail(pp.AttachmentMetadata, "thumbnail", host) + thumb := plugins.Thumbnail(pp.AttachmentMetadata, "thumbnail", host, "thumbnail", "post-thumbnail") if thumb.Path != "" { pp.Thumbnail = thumb } diff --git a/internal/plugins/thumbnail.go b/internal/plugins/thumbnail.go new file mode 100644 index 0000000..a124589 --- /dev/null +++ b/internal/plugins/thumbnail.go @@ -0,0 +1,36 @@ +package plugins + +import ( + "fmt" + "github.com/fthvgb1/wp-go/helper/maps" + "github.com/fthvgb1/wp-go/internal/pkg/models" + "strings" +) + +func Thumbnail(metadata models.WpAttachmentMetadata, Type, host string, except ...string) (r models.PostThumbnail) { + if _, ok := metadata.Sizes[Type]; ok { + r.Path = fmt.Sprintf("%s/wp-content/uploads/%s", host, metadata.File) + r.Width = metadata.Sizes[Type].Width + r.Height = metadata.Sizes[Type].Height + up := strings.Split(metadata.File, "/") + r.Srcset = strings.Join(maps.FilterToSlice[string](metadata.Sizes, func(s string, size models.MetaDataFileSize) (r string, ok bool) { + up[2] = size.File + for _, s2 := range except { + if s == s2 { + return + } + } + r = fmt.Sprintf("%s/wp-content/uploads/%s %dw", host, strings.Join(up, "/"), size.Width) + ok = true + return + }), ", ") + r.Sizes = fmt.Sprintf("(max-width: %dpx) 100vw, %dpx", r.Width, r.Width) + if r.Width >= 740 && r.Width < 767 { + r.Sizes = "(max-width: 706px) 89vw, (max-width: 767px) 82vw, 740px" + } else if r.Width >= 767 { + r.Sizes = "(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px" + } + r.OriginAttachmentData = metadata + } + return +} diff --git a/internal/theme/twentyseventeen/layout/base.gohtml b/internal/theme/twentyseventeen/layout/base.gohtml index 3c35463..d4d3f32 100644 --- a/internal/theme/twentyseventeen/layout/base.gohtml +++ b/internal/theme/twentyseventeen/layout/base.gohtml @@ -6,7 +6,7 @@ {{block "head" .}} {{end}} - + {{template "svg"}}
@@ -16,7 +16,7 @@
- +
@@ -44,21 +44,17 @@ -
-
- {{block "content" .}} + {{block "content" .}} - {{end}} -
+ {{end}} -
+
diff --git a/internal/theme/twentyseventeen/layout/footersvg.gohtml b/internal/theme/twentyseventeen/layout/footersvg.gohtml index 2559db5..b099bab 100644 --- a/internal/theme/twentyseventeen/layout/footersvg.gohtml +++ b/internal/theme/twentyseventeen/layout/footersvg.gohtml @@ -161,4 +161,7 @@ + + {{block "footerx" .}} + {{end}} {{end}} \ No newline at end of file diff --git a/internal/theme/twentyseventeen/layout/head.gohtml b/internal/theme/twentyseventeen/layout/head.gohtml index 653610b..94a4c28 100644 --- a/internal/theme/twentyseventeen/layout/head.gohtml +++ b/internal/theme/twentyseventeen/layout/head.gohtml @@ -14,7 +14,6 @@ - -{{end}} \ No newline at end of file +{{end}} + diff --git a/internal/theme/twentyseventeen/posts/index.gohtml b/internal/theme/twentyseventeen/posts/index.gohtml index 0e4a768..838ddad 100644 --- a/internal/theme/twentyseventeen/posts/index.gohtml +++ b/internal/theme/twentyseventeen/posts/index.gohtml @@ -1,81 +1,86 @@ {{template "layout/base" .}} {{define "content" }} - {{if .posts}} +
+
+ {{if .posts}} -
- +
+ -
-
- {{if .header}} - - {{end}} - {{ range $k,$v:=.posts}} -
+
+
+ {{if .header}} + + {{end}} + {{ range $k,$v:=.posts}} + + + {{end}} + {{template "layout/page" .}} +
+ - +
-
- {{$v.PostContent|unescaped}} -
+ +
- + {{else }} + {{template "layout/empty" .}} + {{end}} + {{end}} - - - - {{end}} - - {{template "layout/page" .}} - - - -
- -
- - {{else }} - {{template "layout/empty" .}} - {{end}} - -{{end}} +
diff --git a/internal/theme/twentyseventeen/twentyseventeen.go b/internal/theme/twentyseventeen/twentyseventeen.go index a284ca7..35fd690 100644 --- a/internal/theme/twentyseventeen/twentyseventeen.go +++ b/internal/theme/twentyseventeen/twentyseventeen.go @@ -1,8 +1,11 @@ package twentyseventeen import ( + "fmt" "github.com/elliotchance/phpserialize" "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/internal/pkg/cache" "github.com/fthvgb1/wp-go/internal/pkg/logs" "github.com/fthvgb1/wp-go/internal/pkg/models" @@ -44,6 +47,7 @@ func Hook(status int, c *gin.Context, h gin.H, scene, stats int) { templ := "twentyseventeen/posts/index.gohtml" if _, ok := plugins.IndexSceneMap[scene]; ok { h["HeaderImage"] = getHeaderImage(c) + posts := h["posts"].([]models.Posts) p, ok := h["pagination"] if ok { pp, ok := p.(pagination.ParsePagination) @@ -51,18 +55,58 @@ func Hook(status int, c *gin.Context, h gin.H, scene, stats int) { h["pagination"] = pagination.Paginate(paginate, pp) } } + d := 0 + s := "" + if scene == plugins.Search { + if len(posts) > 0 { + d = 1 + } else { + d = 0 + } + } else if scene == plugins.Category { + cate := slice.Filter(cache.Categories(c), func(my models.TermsMy) bool { + return my.Name == c.Param("category") + })[0] + d = int(cate.Terms.TermId) + if cate.Slug[0] != '%' { + s = cate.Slug + } + } + h["bodyClass"] = bodyClass(scene, d, s) + h["posts"] = postThumbnail(posts, scene) } else if scene == plugins.Detail { h["HeaderImage"] = getHeaderImage(c) + post := h["post"].(models.Posts) + h["bodyClass"] = bodyClass(scene, int(post.Id)) + host, _ := wpconfig.Options.Load("siteurl") + img := plugins.Thumbnail(post.Thumbnail.OriginAttachmentData, "thumbnail", host, "thumbnail", "post-thumbnail") + img.Width = img.OriginAttachmentData.Width + img.Height = img.OriginAttachmentData.Height + img.Sizes = "100vw" + img.Srcset = fmt.Sprintf("%s %dw, %s", img.Path, img.Width, img.Srcset) + post.Thumbnail = img + h["post"] = post templ = "twentyseventeen/posts/detail.gohtml" } c.HTML(status, templ, h) return } +func postThumbnail(posts []models.Posts, scene int) []models.Posts { + return slice.Map(posts, func(t models.Posts) models.Posts { + if t.Thumbnail.Path != "" { + if slice.IsContained(scene, []int{plugins.Home, plugins.Archive, plugins.Search}) { + t.Thumbnail.Sizes = "(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px" + } else { + t.Thumbnail.Sizes = "100vw" + } + } + return t + }) +} + func getHeaderImage(c *gin.Context) (r models.PostThumbnail) { r.Path = "/wp-content/themes/twentyseventeen/assets/images/header.jpg" - r.Width = 2000 - r.Height = 1200 meta, err := getHeaderMarkup() if err != nil { logs.ErrPrintln(err, "解析主题背景图设置错误") @@ -74,10 +118,18 @@ func getHeaderImage(c *gin.Context) (r models.PostThumbnail) { logs.ErrPrintln(err, "获取主题背景图信息错误") return } + host, _ := wpconfig.Options.Load("siteurl") + m.Thumbnail = plugins.Thumbnail(m.AttachmentMetadata, "thumbnail", host, "thumbnail", "post-thumbnail", "twentyseventeen-thumbnail-avatar") if m.Thumbnail.Path != "" { r = m.Thumbnail + if len(m.AttachmentMetadata.Sizes) > 0 { + r.Srcset = str.Join(r.Path, " 2000vw, ", r.Srcset) + } } } + r.Width = 2000 + r.Height = 1200 + r.Sizes = "100vw" return } @@ -93,3 +145,25 @@ func getHeaderMarkup() (r HeaderImageMeta, err error) { } return } + +func bodyClass(scene, d int, a ...any) string { + s := "" + if scene == plugins.Search { + if d > 0 { + s = "search-results" + } else { + s = "search-no-results" + } + } else if scene == plugins.Category { + s = fmt.Sprintf("category-%d %v", d, a[0]) + } else if scene == plugins.Detail { + s = fmt.Sprintf("postid-%d", d) + } + return map[int]string{ + plugins.Home: "home blog ", + plugins.Archive: "archive date page-two-column", + plugins.Category: str.Join("archive category page-two-column ", s), + plugins.Search: str.Join("search ", s), + plugins.Detail: str.Join("post-template-default single single-post single-format-standard ", s), + }[scene] +} diff --git a/stream/simpleMapStream.go b/stream/simpleMapStream.go index 86c1e10..b3a352c 100644 --- a/stream/simpleMapStream.go +++ b/stream/simpleMapStream.go @@ -1,7 +1,7 @@ package stream import ( - "github.com/fthvgb1/wp-go/safety" + "github.com/fthvgb1/wp-go/helper/maps" "github.com/fthvgb1/wp-go/taskPools" "sync" ) @@ -24,15 +24,8 @@ func newMapX[K comparable, V any]() mapX[K, V] { } } -func SimpleMapFilterAndMapToSlice[R any, K comparable, V any](mm SimpleMapStream[K, V], fn func(K, V) (R, bool), c int) SimpleSliceStream[R] { - rr := safety.NewSlice([]R{}) - mm.ParallelForEach(func(k K, v V) { - vv, ok := fn(k, v) - if ok { - rr.Append(vv) - } - }, c) - return NewSimpleSliceStream(rr.Load()) +func SimpleMapFilterAndMapToSlice[R any, K comparable, V any](mm SimpleMapStream[K, V], fn func(K, V) (R, bool)) SimpleSliceStream[R] { + return NewSimpleSliceStream(maps.FilterToSlice(mm.m, fn)) } func SimpleMapParallelFilterAndMapToMap[K comparable, V any, KK comparable, VV any](mm SimpleMapStream[KK, VV], fn func(KK, VV) (K, V, bool), c int) SimpleMapStream[K, V] {