diff --git a/helper/slice/slice.go b/helper/slice/slice.go
index 0a74454..5ed208f 100644
--- a/helper/slice/slice.go
+++ b/helper/slice/slice.go
@@ -66,6 +66,13 @@ func Reduce[R, T any](arr []T, fn func(T, R) R, r R) R {
return r
}
+func ReverseReduce[R, T any](a []T, fn func(T, R) R, r R) R {
+ for i := len(a) - 1; i >= 0; i-- {
+ r = fn(a[i], r)
+ }
+ return r
+}
+
func Reverse[T any](arr []T) []T {
var r = make([]T, 0, len(arr))
for i := len(arr); i > 0; i-- {
diff --git a/helper/slice/slice_test.go b/helper/slice/slice_test.go
index e4b9968..e54e2c5 100644
--- a/helper/slice/slice_test.go
+++ b/helper/slice/slice_test.go
@@ -840,3 +840,36 @@ func TestShift(t *testing.T) {
})
}
}
+
+func TestReverseReduce(t *testing.T) {
+ type args[T int, R string] struct {
+ a []T
+ fn func(T, R) R
+ r R
+ }
+ type testCase[T int, R string] struct {
+ name string
+ args args[T, R]
+ want R
+ }
+ tests := []testCase[int, string]{
+ {
+ name: "t1",
+ args: args[int, string]{
+ a: number.Range(1, 10, 1),
+ fn: func(i int, r string) string {
+ return fmt.Sprintf("%s%d", r, i)
+ },
+ r: "",
+ },
+ want: "10987654321",
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ if got := ReverseReduce(tt.args.a, tt.args.fn, tt.args.r); !reflect.DeepEqual(got, tt.want) {
+ t.Errorf("ReverseReduce() = %v, want %v", got, tt.want)
+ }
+ })
+ }
+}
diff --git a/helper/slice/sort.go b/helper/slice/sort.go
index 359b4dc..2685c98 100644
--- a/helper/slice/sort.go
+++ b/helper/slice/sort.go
@@ -29,10 +29,8 @@ func SortSelf[T any](arr []T, fn func(i, j T) bool) {
}
func Sort[T any](arr []T, fn func(i, j T) bool) (r []T) {
- r = make([]T, 0, len(arr))
- for _, t := range arr {
- r = append(r, t)
- }
+ r = make([]T, len(arr))
+ copy(r, arr)
slice := anyArr[T]{
data: r,
fn: fn,
diff --git a/internal/actions/detail.go b/internal/actions/detail.go
index f8ff6bf..37dd564 100644
--- a/internal/actions/detail.go
+++ b/internal/actions/detail.go
@@ -8,6 +8,7 @@ import (
"github.com/fthvgb1/wp-go/internal/pkg/models"
"github.com/fthvgb1/wp-go/internal/plugins"
"github.com/fthvgb1/wp-go/internal/theme"
+ "github.com/fthvgb1/wp-go/internal/theme/common"
"github.com/fthvgb1/wp-go/internal/wpconfig"
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin"
@@ -31,6 +32,8 @@ func Detail(c *gin.Context) {
}
isApproveComment := false
status := plugins.Ok
+ pw := sessions.Default(c).Get("post_password")
+
defer func() {
code := http.StatusOK
if err != nil {
@@ -44,7 +47,14 @@ func Detail(c *gin.Context) {
}
t := theme.GetTemplateName()
- theme.Hook(t, code, c, ginH, plugins.Detail, status)
+ theme.Hook(t, common.Handle{
+ C: c,
+ GinH: ginH,
+ Password: "",
+ Scene: plugins.Detail,
+ Code: code,
+ Stats: status,
+ })
}()
ID := str.ToInteger[uint64](c.Param("id"), 0)
@@ -57,7 +67,6 @@ func Detail(c *gin.Context) {
if post.Id == 0 || err != nil || post.PostStatus != "publish" {
return
}
- pw := sessions.Default(c).Get("post_password")
showComment := false
if post.CommentCount > 0 || post.CommentStatus == "open" {
showComment = true
@@ -77,7 +86,6 @@ func Detail(c *gin.Context) {
isApproveComment = true
return
}
- plugins.ApplyPlugin(plugins.NewPostPlugin(c, plugins.Detail), &post)
comments, err := cache.PostComments(c, post.Id)
logs.ErrPrintln(err, "get post comment", post.Id)
ginH["comments"] = comments
diff --git a/internal/actions/feed.go b/internal/actions/feed.go
index 1095bdb..640a88d 100644
--- a/internal/actions/feed.go
+++ b/internal/actions/feed.go
@@ -27,16 +27,17 @@ func isCacheExpired(c *gin.Context, lastTime time.Time) bool {
func Feed(c *gin.Context) {
if !isCacheExpired(c, cache.FeedCache().GetLastSetTime()) {
c.Status(http.StatusNotModified)
- } else {
- r, err := cache.FeedCache().GetCache(c, time.Second, c)
- if err != nil {
- c.Status(http.StatusInternalServerError)
- c.Abort()
- c.Error(err)
- return
- }
- setFeed(r[0], c, cache.FeedCache().GetLastSetTime())
+ return
}
+
+ r, err := cache.FeedCache().GetCache(c, time.Second, c)
+ if err != nil {
+ c.Status(http.StatusInternalServerError)
+ c.Abort()
+ c.Error(err)
+ return
+ }
+ setFeed(r[0], c, cache.FeedCache().GetLastSetTime())
}
func setFeed(s string, c *gin.Context, t time.Time) {
@@ -52,29 +53,29 @@ func PostFeed(c *gin.Context) {
id := c.Param("id")
if !isCacheExpired(c, cache.PostFeedCache().GetLastSetTime(c, id)) {
c.Status(http.StatusNotModified)
- } else {
- s, err := cache.PostFeedCache().GetCache(c, id, time.Second, c, id)
- if err != nil {
- c.Status(http.StatusInternalServerError)
- c.Abort()
- c.Error(err)
- return
- }
- setFeed(s, c, cache.PostFeedCache().GetLastSetTime(c, id))
+ return
}
+ s, err := cache.PostFeedCache().GetCache(c, id, time.Second, c, id)
+ if err != nil {
+ c.Status(http.StatusInternalServerError)
+ c.Abort()
+ c.Error(err)
+ return
+ }
+ setFeed(s, c, cache.PostFeedCache().GetLastSetTime(c, id))
}
func CommentsFeed(c *gin.Context) {
if !isCacheExpired(c, cache.CommentsFeedCache().GetLastSetTime()) {
c.Status(http.StatusNotModified)
- } else {
- r, err := cache.CommentsFeedCache().GetCache(c, time.Second, c)
- if err != nil {
- c.Status(http.StatusInternalServerError)
- c.Abort()
- c.Error(err)
- return
- }
- setFeed(r[0], c, cache.CommentsFeedCache().GetLastSetTime())
+ return
}
+ r, err := cache.CommentsFeedCache().GetCache(c, time.Second, c)
+ if err != nil {
+ c.Status(http.StatusInternalServerError)
+ c.Abort()
+ c.Error(err)
+ return
+ }
+ setFeed(r[0], c, cache.CommentsFeedCache().GetLastSetTime())
}
diff --git a/internal/actions/index.go b/internal/actions/index.go
index bc77bc6..1afc260 100644
--- a/internal/actions/index.go
+++ b/internal/actions/index.go
@@ -14,6 +14,7 @@ import (
"github.com/fthvgb1/wp-go/internal/pkg/models"
"github.com/fthvgb1/wp-go/internal/plugins"
"github.com/fthvgb1/wp-go/internal/theme"
+ "github.com/fthvgb1/wp-go/internal/theme/common"
"github.com/fthvgb1/wp-go/internal/wpconfig"
"github.com/fthvgb1/wp-go/model"
"github.com/fthvgb1/wp-go/plugin/pagination"
@@ -49,7 +50,7 @@ type indexHandle struct {
header string
paginationStep int
scene int
- status int
+ stats int
}
func newIndexHandle(ctx *gin.Context) *indexHandle {
@@ -71,7 +72,7 @@ func newIndexHandle(ctx *gin.Context) *indexHandle {
postType: []any{"post"},
postStatus: []any{"publish"},
scene: plugins.Home,
- status: plugins.Ok,
+ stats: plugins.Ok,
}
}
@@ -233,20 +234,32 @@ func Index(c *gin.Context) {
"recentComments": recentComments,
"posts": posts,
}
+ pw := h.session.Get("post_password")
+ pws, ok := pw.(string)
+ if !ok {
+ pws = ""
+ }
defer func() {
code := http.StatusOK
if err != nil {
code = http.StatusNotFound
- if h.status == plugins.InternalErr {
+ if h.stats == plugins.InternalErr {
code = http.StatusInternalServerError
c.Error(err)
return
}
c.Error(err)
- h.status = plugins.Error
+ h.stats = plugins.Error
}
t := theme.GetTemplateName()
- theme.Hook(t, code, c, ginH, h.scene, h.status)
+ theme.Hook(t, common.Handle{
+ C: c,
+ GinH: ginH,
+ Password: pws,
+ Scene: h.scene,
+ Code: code,
+ Stats: h.stats,
+ })
}()
err = h.parseParams()
if err != nil {
@@ -264,29 +277,15 @@ func Index(c *gin.Context) {
posts, totalRaw, err = cache.PostLists(c, h.getSearchKey(), c, h.where, h.page, h.pageSize, model.SqlBuilder{{h.orderBy, h.order}}, h.join, h.postType, h.postStatus)
}
if err != nil {
- h.status = plugins.Error
+ h.stats = plugins.Error
logs.ErrPrintln(err, "获取数据错误")
return
}
if len(posts) < 1 && h.category != "" {
h.titleL = "未找到页面"
- h.status = plugins.Empty404
+ h.stats = plugins.Empty404
}
-
- pw := h.session.Get("post_password")
- plug := plugins.NewPostPlugin(c, h.scene)
- for i, post := range posts {
- if post.PostPassword != "" {
- plugins.PasswordProjectTitle(&posts[i])
- if pw != post.PostPassword {
- plugins.PasswdProjectContent(&posts[i])
- }
- } else {
- plugins.ApplyPlugin(plug, &posts[i])
- }
- }
-
q := c.Request.URL.Query().Encode()
if q != "" {
q = fmt.Sprintf("?%s", q)
diff --git a/internal/pkg/cache/feed.go b/internal/pkg/cache/feed.go
index e4a5518..7f1428a 100644
--- a/internal/pkg/cache/feed.go
+++ b/internal/pkg/cache/feed.go
@@ -25,7 +25,7 @@ func InitFeed() {
AtomLink: fmt.Sprintf("%s/feed", wpconfig.Options.Value("home")),
Link: wpconfig.Options.Value("siteurl"),
Description: wpconfig.Options.Value("blogdescription"),
- Language: "zh-CN",
+ Language: wpconfig.GetLang(),
UpdatePeriod: "hourly",
UpdateFrequency: 1,
Generator: wpconfig.Options.Value("home"),
diff --git a/internal/plugins/digest.go b/internal/plugins/digest.go
index d2d97fd..93d46e4 100644
--- a/internal/plugins/digest.go
+++ b/internal/plugins/digest.go
@@ -7,7 +7,6 @@ import (
"github.com/fthvgb1/wp-go/internal/pkg/config"
"github.com/fthvgb1/wp-go/internal/pkg/models"
"github.com/fthvgb1/wp-go/plugin/digest"
- "github.com/gin-gonic/gin"
"strings"
"time"
)
@@ -30,7 +29,7 @@ func FlushCache() {
func digestRaw(arg ...any) (string, error) {
str := arg[0].(string)
id := arg[1].(uint64)
- limit := config.GetConfig().DigestWordCount
+ limit := arg[2].(int)
if limit < 0 {
return str, nil
} else if limit == 0 {
@@ -39,20 +38,11 @@ func digestRaw(arg ...any) (string, error) {
return digest.Raw(str, limit, fmt.Sprintf("/p/%d", id)), nil
}
-func Digest(p *Plugin[models.Posts], c *gin.Context, post *models.Posts, scene int) {
- if scene == Detail {
- return
- }
- if post.PostExcerpt != "" {
- post.PostContent = strings.Replace(post.PostExcerpt, "\n", "
", -1)
- } else {
- post.PostContent = DigestCache(c, post.Id, post.PostContent)
-
- }
- p.Next()
+func Digest(ctx context.Context, post *models.Posts, limit int) {
+ content, _ := digestCache.GetCache(ctx, post.Id, time.Second, post.PostContent, post.Id, limit)
+ post.PostContent = content
}
-func DigestCache(ctx *gin.Context, id uint64, str string) string {
- content, _ := digestCache.GetCache(ctx, id, time.Second, str, id)
- return content
+func PostExcerpt(post *models.Posts) {
+ post.PostContent = strings.Replace(post.PostExcerpt, "\n", "
", -1)
}
diff --git a/internal/plugins/plugins.go b/internal/plugins/plugins.go
index 13568c7..81387e8 100644
--- a/internal/plugins/plugins.go
+++ b/internal/plugins/plugins.go
@@ -35,18 +35,3 @@ type Plugin[T any] struct {
scene int
c *gin.Context
}
-
-func NewPlugin[T any](calls []Func[T], index int, post *T, scene int, c *gin.Context) *Plugin[T] {
- return &Plugin[T]{calls: calls, index: index, post: post, scene: scene, c: c}
-}
-
-func (p *Plugin[T]) Push(call ...Func[T]) {
- p.calls = append(p.calls, call...)
-}
-
-func (p *Plugin[T]) Next() {
- p.index++
- for ; p.index < len(p.calls); p.index++ {
- p.calls[p.index](p, p.c, p.post, p.scene)
- }
-}
diff --git a/internal/plugins/posts.go b/internal/plugins/posts.go
index 711728d..c241f32 100644
--- a/internal/plugins/posts.go
+++ b/internal/plugins/posts.go
@@ -3,21 +3,8 @@ package plugins
import (
"fmt"
"github.com/fthvgb1/wp-go/internal/pkg/models"
- "github.com/gin-gonic/gin"
)
-func NewPostPlugin(ctx *gin.Context, scene int) *Plugin[models.Posts] {
- p := NewPlugin[models.Posts](nil, -1, nil, scene, ctx)
- p.Push(Digest)
- return p
-}
-
-func ApplyPlugin(p *Plugin[models.Posts], post *models.Posts) {
- p.post = post
- p.Next()
- p.index = -1
-}
-
func PasswordProjectTitle(post *models.Posts) {
post.PostTitle = fmt.Sprintf("密码保护:%s", post.PostTitle)
}
diff --git a/internal/theme/common/common.go b/internal/theme/common/common.go
new file mode 100644
index 0000000..ba85789
--- /dev/null
+++ b/internal/theme/common/common.go
@@ -0,0 +1,55 @@
+package common
+
+import (
+ "github.com/fthvgb1/wp-go/helper/slice"
+ "github.com/fthvgb1/wp-go/internal/pkg/config"
+ "github.com/fthvgb1/wp-go/internal/pkg/models"
+ "github.com/fthvgb1/wp-go/internal/plugins"
+ "github.com/gin-gonic/gin"
+)
+
+type Handle struct {
+ C *gin.Context
+ GinH gin.H
+ Password string
+ Scene int
+ Code int
+ Stats int
+}
+
+type Fn[T any] func(T) T
+type Plugin[T any] func(next Fn[T], h Handle, t T) T
+
+func PluginFn[T any](a []Plugin[T], h Handle, fn Fn[T]) Fn[T] {
+ return slice.ReverseReduce(a, func(next Plugin[T], forward Fn[T]) Fn[T] {
+ return func(t T) T {
+ return next(forward, h, t)
+ }
+ }, fn)
+}
+
+func Default[T any](t T) T {
+ return t
+}
+
+func PasswordProject(next Fn[models.Posts], h Handle, post models.Posts) (r models.Posts) {
+ r = post
+ if post.PostPassword != "" {
+ plugins.PasswordProjectTitle(&r)
+ if h.Password != post.PostPassword {
+ plugins.PasswdProjectContent(&r)
+ return
+ }
+ }
+ r = next(r)
+ return
+}
+
+func Digest(next Fn[models.Posts], h Handle, post models.Posts) models.Posts {
+ if post.PostExcerpt != "" {
+ plugins.PostExcerpt(&post)
+ } else {
+ plugins.Digest(h.C, &post, config.GetConfig().DigestWordCount)
+ }
+ return next(post)
+}
diff --git a/internal/theme/hook.go b/internal/theme/hook.go
index 3c7fa88..bb010ae 100644
--- a/internal/theme/hook.go
+++ b/internal/theme/hook.go
@@ -1,30 +1,25 @@
package theme
import (
- "errors"
- "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/plugin/pagination"
- "github.com/gin-gonic/gin"
+ "github.com/fthvgb1/wp-go/internal/theme/common"
)
-var themeMap = map[string]func(int, *gin.Context, gin.H, int, int){}
+var themeMap = map[string]func(handle common.Handle){}
-func addThemeHookFunc(name string, fn func(int, *gin.Context, gin.H, int, int)) {
+func addThemeHookFunc(name string, fn func(handle common.Handle)) {
if _, ok := themeMap[name]; ok {
panic("exists same name theme")
}
themeMap[name] = fn
}
-func Hook(themeName string, code int, c *gin.Context, h gin.H, scene, status int) {
+func Hook(themeName string, handle common.Handle) {
fn, ok := themeMap[themeName]
if ok && fn != nil {
- fn(code, c, h, scene, status)
+ fn(handle)
return
}
- if _, ok := plugins.IndexSceneMap[scene]; ok {
+ /*if _, ok := plugins.IndexSceneMap[scene]; ok {
p, ok := h["pagination"]
if ok {
pp, ok := p.(pagination.ParsePagination)
@@ -39,5 +34,5 @@ func Hook(themeName string, code int, c *gin.Context, h gin.H, scene, status int
c.HTML(code, "twentyfifteen/posts/detail.gohtml", h)
return
}
- logs.ErrPrintln(errors.New("what happening"), " how reached here", themeName, code, h, scene, status)
+ logs.ErrPrintln(errors.New("what happening"), " how reached here", themeName, code, h, scene, status)*/
}
diff --git a/internal/theme/twentyseventeen/twentyseventeen.go b/internal/theme/twentyseventeen/twentyseventeen.go
index 7f3df32..61b11d6 100644
--- a/internal/theme/twentyseventeen/twentyseventeen.go
+++ b/internal/theme/twentyseventeen/twentyseventeen.go
@@ -8,6 +8,7 @@ import (
"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/internal/theme/common"
"github.com/fthvgb1/wp-go/plugin/pagination"
"github.com/gin-gonic/gin"
"strings"
@@ -26,53 +27,52 @@ var paginate = func() plugins.PageEle {
}()
type handle struct {
- c *gin.Context
- ginH gin.H
- scene int
- status int
- stats int
- templ string
+ common.Handle
+ templ string
}
-func Hook(status int, c *gin.Context, ginH gin.H, scene, stats int) {
+func Hook(h2 common.Handle) {
h := handle{
- c: c,
- ginH: ginH,
- scene: scene,
- status: status,
- stats: stats,
+ Handle: h2,
templ: "twentyseventeen/posts/index.gohtml",
}
- ginH["HeaderImage"] = h.getHeaderImage(c)
- if stats == plugins.Empty404 {
- c.HTML(status, h.templ, ginH)
+ h.GinH["HeaderImage"] = h.getHeaderImage(h.C)
+ if h.Stats == plugins.Empty404 {
+ h.C.HTML(h.Code, h.templ, h.GinH)
return
}
- if scene == plugins.Detail {
+ if h.Scene == plugins.Detail {
h.detail()
return
}
h.index()
+}
+var plugin = []common.Plugin[models.Posts]{
+ common.PasswordProject, common.Digest,
}
func (h handle) index() {
- posts := h.ginH["posts"].([]models.Posts)
- p, ok := h.ginH["pagination"]
- if ok {
- pp, ok := p.(pagination.ParsePagination)
+ if h.Stats != plugins.Empty404 {
+ posts := h.GinH["posts"].([]models.Posts)
+ posts = slice.Map(posts, common.PluginFn(plugin, h.Handle, common.Default[models.Posts]))
+ p, ok := h.GinH["pagination"]
if ok {
- h.ginH["pagination"] = pagination.Paginate(paginate, pp)
+ pp, ok := p.(pagination.ParsePagination)
+ if ok {
+ h.GinH["pagination"] = pagination.Paginate(paginate, pp)
+ }
}
+ h.GinH["posts"] = h.postThumbnail(posts, h.Scene)
}
- h.ginH["bodyClass"] = h.bodyClass()
- h.ginH["posts"] = h.postThumbnail(posts, h.scene)
- h.c.HTML(h.status, h.templ, h.ginH)
+
+ h.GinH["bodyClass"] = h.bodyClass()
+ h.C.HTML(h.Code, h.templ, h.GinH)
}
func (h handle) detail() {
- post := h.ginH["post"].(models.Posts)
- h.ginH["bodyClass"] = h.bodyClass()
+ post := h.GinH["post"].(models.Posts)
+ h.GinH["bodyClass"] = h.bodyClass()
//host, _ := wpconfig.Options.Load("siteurl")
host := ""
img := plugins.Thumbnail(post.Thumbnail.OriginAttachmentData, "thumbnail", host, "thumbnail", "post-thumbnail")
@@ -81,12 +81,12 @@ func (h handle) detail() {
img.Sizes = "100vw"
img.Srcset = fmt.Sprintf("%s %dw, %s", img.Path, img.Width, img.Srcset)
post.Thumbnail = img
- h.ginH["post"] = post
- comments := h.ginH["comments"].([]models.Comments)
- dep := h.ginH["maxDep"].(int)
- h.ginH["comments"] = plugins.FormatComments(h.c, comment{}, comments, dep)
+ h.GinH["post"] = post
+ comments := h.GinH["comments"].([]models.Comments)
+ dep := h.GinH["maxDep"].(int)
+ h.GinH["comments"] = plugins.FormatComments(h.C, comment{}, comments, dep)
h.templ = "twentyseventeen/posts/detail.gohtml"
- h.c.HTML(h.status, h.templ, h.ginH)
+ h.C.HTML(h.Code, h.templ, h.GinH)
}
type comment struct {
@@ -137,18 +137,18 @@ func (h handle) getHeaderImage(c *gin.Context) (r models.PostThumbnail) {
func (h handle) bodyClass() string {
s := ""
- switch h.scene {
+ switch h.Scene {
case plugins.Search:
s = "search-no-results"
- if len(h.ginH["posts"].([]models.Posts)) > 0 {
+ if len(h.GinH["posts"].([]models.Posts)) > 0 {
s = "search-results"
}
case plugins.Category, plugins.Tag:
- cat := h.c.Param("category")
+ cat := h.C.Param("category")
if cat == "" {
- cat = h.c.Param("tag")
+ cat = h.C.Param("tag")
}
- _, cate := slice.SearchFirst(cache.CategoriesTags(h.c, h.scene), func(my models.TermsMy) bool {
+ _, cate := slice.SearchFirst(cache.CategoriesTags(h.C, h.Scene), func(my models.TermsMy) bool {
return my.Name == cat
})
if cate.Slug[0] != '%' {
@@ -156,9 +156,9 @@ func (h handle) bodyClass() string {
}
s = fmt.Sprintf("category-%d %v", cate.Terms.TermId, s)
case plugins.Detail:
- s = fmt.Sprintf("postid-%d", h.ginH["post"].(models.Posts).Id)
+ s = fmt.Sprintf("postid-%d", h.GinH["post"].(models.Posts).Id)
}
- return str.Join(class[h.scene], s)
+ return str.Join(class[h.Scene], s)
}
var class = map[int]string{