fix bug, optimize code, add some cache comments, add middleware,change pagination nav to mix url plain

This commit is contained in:
xing 2024-01-13 21:15:54 +08:00
parent 6044b8eaec
commit 0352dd0fd0
18 changed files with 353 additions and 152 deletions

View File

@ -7,7 +7,6 @@ import (
"github.com/fthvgb1/wp-go/app/pkg/logs"
"github.com/fthvgb1/wp-go/app/pkg/models"
"github.com/fthvgb1/wp-go/cache/cachemanager"
"github.com/fthvgb1/wp-go/helper/slice"
"github.com/fthvgb1/wp-go/safety"
"time"
)
@ -78,7 +77,7 @@ func InitActionsCommonCache() {
return config.GetConfig().CacheTime.UserInfoCacheTime
})
cachemanager.NewMemoryMapCache(nil, dao.GetUserByName, c.CacheTime.UserInfoCacheTime, "usernameMapToUserData", func() time.Duration {
cachemanager.NewMemoryMapCache(nil, dao.GetUserByName, c.CacheTime.UserInfoCacheTime, "usernameToUserData", func() time.Duration {
return config.GetConfig().CacheTime.UserInfoCacheTime
})
@ -88,7 +87,7 @@ func InitActionsCommonCache() {
cachemanager.NewVarMemoryCache(feed, time.Hour, "feed")
cachemanager.NewMemoryMapCache(nil, postFeed, time.Hour, "postFeed")
cachemanager.NewMemoryMapCache(nil, PostFeed, time.Hour, "postFeed")
cachemanager.NewVarMemoryCache(commentsFeed, time.Hour, "commentsFeed")
@ -125,30 +124,3 @@ func Archives(ctx context.Context) []models.PostArchive {
}
return data
}
// CategoriesTags categories or tags
//
// t is constraints.Tag or constraints.Category
func CategoriesTags(ctx context.Context, t ...string) []models.TermsMy {
tt := ""
if len(t) > 0 {
tt = t[0]
}
r, err := cachemanager.GetBy[[]models.TermsMy]("categoryAndTagsData", ctx, tt, time.Second)
logs.IfError(err, "get category fail")
return r
}
func AllCategoryTagsNames(ctx context.Context, t ...string) map[string]struct{} {
tt := ""
if len(t) > 0 {
tt = t[0]
}
r, err := cachemanager.GetBy[[]models.TermsMy]("categoryAndTagsData", ctx, tt, time.Second)
if err != nil {
logs.Error(err, "get category fail")
return nil
}
return slice.ToMap(r, func(t models.TermsMy) (string, struct{}) {
return t.Name, struct{}{}
}, true)
}

39
app/pkg/cache/categoryandtag.go vendored Normal file
View File

@ -0,0 +1,39 @@
package cache
import (
"context"
"github.com/fthvgb1/wp-go/app/pkg/logs"
"github.com/fthvgb1/wp-go/app/pkg/models"
"github.com/fthvgb1/wp-go/cache/cachemanager"
"github.com/fthvgb1/wp-go/helper/slice"
"time"
)
// CategoriesTags get all categories or tags
//
// query func see dao.CategoriesAndTags
//
// t is constraints.Tag or constraints.Category
func CategoriesTags(ctx context.Context, t ...string) []models.TermsMy {
tt := ""
if len(t) > 0 {
tt = t[0]
}
r, err := cachemanager.GetBy[[]models.TermsMy]("categoryAndTagsData", ctx, tt, time.Second)
logs.IfError(err, "get category fail")
return r
}
func AllCategoryTagsNames(ctx context.Context, t ...string) map[string]struct{} {
tt := ""
if len(t) > 0 {
tt = t[0]
}
r, err := cachemanager.GetBy[[]models.TermsMy]("categoryAndTagsData", ctx, tt, time.Second)
if err != nil {
logs.Error(err, "get category fail")
return nil
}
return slice.ToMap(r, func(t models.TermsMy) (string, struct{}) {
return t.Name, struct{}{}
}, true)
}

View File

@ -9,11 +9,13 @@ import (
"github.com/fthvgb1/wp-go/app/wpconfig"
"github.com/fthvgb1/wp-go/cache"
"github.com/fthvgb1/wp-go/cache/cachemanager"
"github.com/fthvgb1/wp-go/helper"
"github.com/fthvgb1/wp-go/helper/number"
str "github.com/fthvgb1/wp-go/helper/strings"
"time"
)
// RecentComments query func see RecentComment
func RecentComments(ctx context.Context, n int) (r []models.Comments) {
nn := number.Max(n, 10)
r, err := cachemanager.GetVarVal[[]models.Comments]("recentComments", ctx, time.Second, ctx, nn)
@ -24,18 +26,25 @@ func RecentComments(ctx context.Context, n int) (r []models.Comments) {
return
}
func PostComments(ctx context.Context, Id uint64) ([]models.Comments, error) {
ids, err := cachemanager.GetBy[[]uint64]("PostCommentsIds", ctx, Id, time.Second)
if err != nil {
return nil, err
// PostTopLevelCommentIds query func see PostTopComments
func PostTopLevelCommentIds(ctx context.Context, postId uint64, page, limit, total int, order string, a ...any) ([]uint64, error) {
var key string
if len(a) > 0 {
key = helper.ParseArgs("", a...)
}
return GetCommentDataByIds(ctx, ids)
if key == "" {
key = fmt.Sprintf("%d-%d-%d-%d-%s", postId, page, limit, total, order)
}
return cachemanager.GetBy[[]uint64]("PostCommentsIds", ctx,
key, time.Second, postId, page, limit, 0, order)
}
// GetCommentById query func see dao.GetCommentByIds
func GetCommentById(ctx context.Context, id uint64) (models.Comments, error) {
return cachemanager.GetBy[models.Comments]("postCommentData", ctx, id, time.Second)
}
// GetCommentDataByIds query func see dao.GetCommentByIds
func GetCommentDataByIds(ctx context.Context, ids []uint64) ([]models.Comments, error) {
return cachemanager.GetBatchBy[models.Comments]("postCommentData", ctx, ids, time.Second)
}
@ -50,7 +59,11 @@ func PostTopComments(ctx context.Context, _ string, a ...any) ([]uint64, error)
page := a[1].(int)
limit := a[2].(int)
total := a[3].(int)
v, _, err := dao.PostCommentsIds(ctx, postId, page, limit, total)
order := helper.ParseArgs("", a...)
if order == "" {
order = wpconfig.GetOption("comment_order")
}
v, _, err := dao.PostCommentsIds(ctx, postId, page, limit, total, order)
if err != nil {
return nil, err
}
@ -100,7 +113,7 @@ func GetCommentUrl(ctx context.Context, commentId, postId uint64) (string, error
}
func AncestorCommentId(ctx context.Context, commentId uint64) (uint64, error) {
comment, err := cachemanager.GetBy[models.Comments]("postCommentData", ctx, commentId, time.Second)
comment, err := GetCommentById(ctx, commentId)
if err != nil {
return 0, err
}

28
app/pkg/cache/feed.go vendored
View File

@ -2,6 +2,7 @@ package cache
import (
"context"
"errors"
"fmt"
"github.com/fthvgb1/wp-go/app/pkg/logs"
"github.com/fthvgb1/wp-go/app/pkg/models"
@ -44,6 +45,7 @@ func FeedCache() *cache.VarCache[[]string] {
return r
}
// PostFeedCache query func see PostFeed
func PostFeedCache() *cache.MapCache[string, string] {
r, _ := cachemanager.GetMapCache[string, string]("postFeed")
return r
@ -95,7 +97,7 @@ func feed(c context.Context, _ ...any) (xml []string, err error) {
return
}
func postFeed(c context.Context, id string, _ ...any) (x string, err error) {
func PostFeed(c context.Context, id string, _ ...any) (x string, err error) {
ID := str.ToInteger[uint64](id, 0)
maxId, err := GetMaxPostId(c)
logs.IfError(err, "get max post id")
@ -107,11 +109,11 @@ func postFeed(c context.Context, id string, _ ...any) (x string, err error) {
return
}
limit := str.ToInteger(wpconfig.GetOption("comments_per_page"), 10)
ids, _, err := cachemanager.Pagination[uint64]("PostCommentsIds", c, time.Second, ID, 1, limit, "desc")
ids, err := PostTopLevelCommentIds(c, ID, 1, limit, 0, "desc", "latest-comment")
if err != nil {
return
}
comments, err := cachemanager.GetBatchBy[models.Comments]("postCommentData", c, ids, time.Second)
comments, err := GetCommentDataByIds(c, ids)
if err != nil {
return
}
@ -127,10 +129,14 @@ func postFeed(c context.Context, id string, _ ...any) (x string, err error) {
wpposts.PasswdProjectContent(&post)
if len(comments) > 0 {
t := comments[len(comments)-1]
u, err := GetCommentUrl(c, t.CommentId, t.CommentPostId)
if err != nil {
return "", err
}
rs.Items = []rss2.Item{
{
Title: fmt.Sprintf("评价者:%s", t.CommentAuthor),
Link: fmt.Sprintf("%s/p/%d#comment-%d", site, post.Id, t.CommentId),
Link: fmt.Sprintf("%s%s", site, u),
Creator: t.CommentAuthor,
PubDate: t.CommentDateGmt.Format(timeFormat),
Guid: fmt.Sprintf("%s#comment-%d", post.Guid, t.CommentId),
@ -141,9 +147,14 @@ func postFeed(c context.Context, id string, _ ...any) (x string, err error) {
}
} else {
rs.Items = slice.Map(comments, func(t models.Comments) rss2.Item {
u, er := GetCommentUrl(c, t.CommentId, t.CommentPostId)
if er != nil {
err = errors.Join(err, er)
return rss2.Item{}
}
return rss2.Item{
Title: fmt.Sprintf("评价者:%s", t.CommentAuthor),
Link: fmt.Sprintf("%s/p/%d#comment-%d", site, post.Id, t.CommentId),
Link: fmt.Sprintf("%s%s", site, u),
Creator: t.CommentAuthor,
PubDate: t.CommentDateGmt.Format(timeFormat),
Guid: fmt.Sprintf("%s#comment-%d", post.Guid, t.CommentId),
@ -180,9 +191,14 @@ func commentsFeed(c context.Context, _ ...any) (r []string, err error) {
} else {
content = digest.StripTags(t.CommentContent, "")
}
u, er := GetCommentUrl(c, t.CommentId, t.CommentPostId)
if er != nil {
errors.Join(err, er)
}
u = str.Join(site, u)
return rss2.Item{
Title: fmt.Sprintf("%s对《%s》的评论", t.CommentAuthor, post.PostTitle),
Link: t.CommentAuthorUrl,
Link: u,
Creator: t.CommentAuthor,
Description: desc,
PubDate: t.CommentDateGmt.Format(timeFormat),

View File

@ -6,9 +6,12 @@ import (
"time"
)
// GetPostMetaByPostIds query func see dao.GetPostMetaByPostIds
func GetPostMetaByPostIds(ctx context.Context, ids []uint64) ([]map[string]any, error) {
return cachemanager.GetBatchBy[map[string]any]("postMetaData", ctx, ids, time.Second)
}
// GetPostMetaByPostId query func see dao.GetPostMetaByPostIds
func GetPostMetaByPostId(ctx context.Context, id uint64) (map[string]any, error) {
return cachemanager.GetBy[map[string]any]("postMetaData", ctx, id, time.Second)
}

View File

@ -14,14 +14,17 @@ import (
"time"
)
// GetPostById query func see dao.GetPostsByIds
func GetPostById(ctx context.Context, id uint64) (models.Posts, error) {
return cachemanager.GetBy[models.Posts]("postData", ctx, id, time.Second)
}
// GetPostsByIds query func see dao.GetPostsByIds
func GetPostsByIds(ctx context.Context, ids []uint64) ([]models.Posts, error) {
return cachemanager.GetBatchBy[models.Posts]("postData", ctx, ids, time.Second)
}
// SearchPost query func see dao.SearchPostIds
func SearchPost(ctx context.Context, key string, args ...any) (r []models.Posts, total int, err error) {
ids, err := cachemanager.GetBy[dao.PostIds]("searchPostIds", ctx, key, time.Second, args...)
if err != nil {
@ -32,6 +35,7 @@ func SearchPost(ctx context.Context, key string, args ...any) (r []models.Posts,
return
}
// PostLists query func see dao.SearchPostIds
func PostLists(ctx context.Context, key string, args ...any) (r []models.Posts, total int, err error) {
ids, err := cachemanager.GetBy[dao.PostIds]("listPostIds", ctx, key, time.Second, args...)
if err != nil {
@ -42,10 +46,12 @@ func PostLists(ctx context.Context, key string, args ...any) (r []models.Posts,
return
}
// GetMaxPostId query func see dao.GetMaxPostId
func GetMaxPostId(ctx context.Context) (uint64, error) {
return cachemanager.GetVarVal[uint64]("maxPostId", ctx, time.Second)
}
// RecentPosts query func see dao.RecentPosts
func RecentPosts(ctx context.Context, n int) (r []models.Posts) {
nn := n
feedNum := str.ToInteger(wpconfig.GetOption("posts_per_rss"), 10)
@ -58,6 +64,7 @@ func RecentPosts(ctx context.Context, n int) (r []models.Posts) {
return
}
// GetContextPost query func see dao.GetPostContext
func GetContextPost(ctx context.Context, id uint64, date time.Time) (prev, next models.Posts, err error) {
postCtx, err := cachemanager.GetBy[dao.PostContext]("postContext", ctx, id, time.Second, date)
if err != nil {
@ -68,6 +75,7 @@ func GetContextPost(ctx context.Context, id uint64, date time.Time) (prev, next
return
}
// GetMonthPostIds query func see dao.MonthPost
func GetMonthPostIds(ctx context.Context, year, month string, page, limit int, order string) (r []models.Posts, total int, err error) {
res, err := cachemanager.GetBy[[]uint64]("monthPostIds", ctx, fmt.Sprintf("%s%s", year, month), time.Second, year, month)
if err != nil {

View File

@ -8,14 +8,17 @@ import (
"time"
)
// GetUserByName query func see dao.GetUserByName
func GetUserByName(ctx context.Context, username string) (models.Users, error) {
return cachemanager.GetBy[models.Users]("usernameMapToUserData", ctx, username, time.Second)
return cachemanager.GetBy[models.Users]("usernameToUserData", ctx, username, time.Second)
}
func GetAllUsername(ctx context.Context) (map[string]struct{}, error) {
return cachemanager.GetVarVal[map[string]struct{}]("allUsername", ctx, time.Second)
// GetAllUsername query func see dao.AllUsername
func GetAllUsername(ctx context.Context) (map[string]uint64, error) {
return cachemanager.GetVarVal[map[string]uint64]("allUsername", ctx, time.Second)
}
// GetUserById query func see dao.GetUserById
func GetUserById(ctx context.Context, uid uint64) models.Users {
r, err := cachemanager.GetBy[models.Users]("userData", ctx, uid, time.Second)
logs.IfError(err, "get user", uid)

View File

@ -114,9 +114,7 @@ func postTopCommentNumWhere(postId uint64) model.SqlBuilder {
return where
}
func PostCommentsIds(ctx context.Context, postId uint64, page, limit, totalRaw int, _ ...any) ([]uint64, int, error) {
order := wpconfig.GetOption("comment_order")
pageComments := wpconfig.GetOption("page_comments")
func PostCommentsIds(ctx context.Context, postId uint64, page, limit, totalRaw int, order string) ([]uint64, int, error) {
condition := model.Conditions(
model.Where(postTopCommentNumWhere(postId)),
model.TotalRaw(totalRaw),
@ -129,7 +127,7 @@ func PostCommentsIds(ctx context.Context, postId uint64, page, limit, totalRaw i
var r []models.Comments
var total int
var err error
if pageComments != "1" {
if limit < 1 {
r, err = model.ChunkFind[models.Comments](ctx, 300, condition)
total = len(r)
} else {

View File

@ -12,21 +12,21 @@ func GetUserById(ctx context.Context, uid uint64, _ ...any) (r models.Users, err
return
}
func AllUsername(ctx context.Context, _ ...any) (map[string]struct{}, error) {
func AllUsername(ctx context.Context, _ ...any) (map[string]uint64, error) {
r, err := model.SimpleFind[models.Users](ctx, model.SqlBuilder{
{"user_status", "=", "0", "int"},
}, "user_login")
}, "display_name,ID")
if err != nil {
return nil, err
}
return slice.ToMap(r, func(t models.Users) (string, struct{}) {
return t.UserLogin, struct{}{}
return slice.ToMap(r, func(t models.Users) (string, uint64) {
return t.DisplayName, t.Id
}, true), nil
}
func GetUserByName(ctx context.Context, u string, _ ...any) (r models.Users, err error) {
r, err = model.FirstOne[models.Users](ctx, model.SqlBuilder{{
"user_login", u,
"display_name", u,
}}, "*", nil)
return
}

View File

@ -7,6 +7,7 @@ import (
str "github.com/fthvgb1/wp-go/helper/strings"
"net/url"
"regexp"
"strconv"
"strings"
)
@ -72,8 +73,20 @@ func (p PageEle) Middle(page int, url string) string {
var reg = regexp.MustCompile(`(/page)/(\d+)`)
var commentReg = regexp.MustCompile(`/comment-page-(\d+)`)
var queryParam = []string{"paged", "cat", "m", "author", "tag"}
func (p PageEle) Urls(u url.URL, page int, isTLS bool) string {
var path, query = u.Path, u.RawQuery
if path == "/" {
v := u.Query()
for _, q := range queryParam {
if v.Get(q) != "" {
v.Set("paged", strconv.Itoa(page))
return str.Join(path, "?", v.Encode())
}
}
}
if !strings.Contains(path, "/page/") {
path = fmt.Sprintf("%s%s", path, "/page/1")
}
@ -87,20 +100,32 @@ func (p PageEle) Urls(u url.URL, page int, isTLS bool) string {
if path == "" {
path = "/"
}
return str.Join(path, query)
if query != "" {
return str.Join(path, "?", query)
}
return path
}
func (p CommentPageEle) Urls(u url.URL, page int, isTLS bool) string {
var path, query = u.Path, u.RawQuery
if path == "/" {
v := u.Query()
if v.Get("p") != "" {
v.Set("cpage", strconv.Itoa(page))
return str.Join(path, "?", v.Encode(), "#comments")
}
}
if !strings.Contains(path, "/comment-page-") {
path = fmt.Sprintf("%s%s", path, "/comment-page-1#comments")
path = fmt.Sprintf("%s%s", path, "/comment-page-1")
}
path = commentReg.ReplaceAllString(path, fmt.Sprintf("/comment-page-%d", page))
path = strings.Replace(path, "//", "/", -1)
ur := str.Join(path, query)
if !strings.Contains(ur, "#comments") {
ur = str.Join(ur, "#comments")
ur := path
if query != "" {
ur = str.Join(path, "?", query)
}
ur = str.Join(ur, "#comments")
return ur
}

View File

@ -6,7 +6,7 @@ import (
"github.com/fthvgb1/wp-go/app/plugins"
"github.com/fthvgb1/wp-go/app/theme/wp"
"github.com/fthvgb1/wp-go/app/theme/wp/components"
"github.com/fthvgb1/wp-go/app/theme/wp/components/widget"
"github.com/fthvgb1/wp-go/app/theme/wp/middleware"
"github.com/fthvgb1/wp-go/app/wpconfig"
"strings"
)
@ -22,13 +22,7 @@ func configs(h *wp.Handle) {
return strings.ReplaceAll(s, `class="search-submit"`, `class="search-submit screen-reader-text"`)
})
wp.InitPipe(h)
h.PushHandler(constraints.PipeMiddleware, constraints.Home,
wp.NewHandleFn(widget.CheckCategory, 100, "widget.CheckCategory"),
)
h.PushHandler(constraints.PipeMiddleware, constraints.Detail,
wp.NewHandleFn(wp.ShowPreComment, 100, "wp.ShowPreComment"),
)
middleware.CommonMiddleware(h)
h.Index.SetPageEle(plugins.TwentyFifteenPagination())
h.PushCacheGroupHeadScript(constraints.AllScene, "CalCustomBackGround", 10.005, CalCustomBackGround)
h.PushCacheGroupHeadScript(constraints.AllScene, "colorSchemeCss", 10.0056, colorSchemeCss)

View File

@ -10,7 +10,7 @@ import (
"github.com/fthvgb1/wp-go/app/plugins"
"github.com/fthvgb1/wp-go/app/theme/wp"
"github.com/fthvgb1/wp-go/app/theme/wp/components"
"github.com/fthvgb1/wp-go/app/theme/wp/components/widget"
"github.com/fthvgb1/wp-go/app/theme/wp/middleware"
"github.com/fthvgb1/wp-go/app/wpconfig"
"github.com/fthvgb1/wp-go/cache/reload"
"github.com/fthvgb1/wp-go/helper"
@ -51,11 +51,7 @@ func Hook(h *wp.Handle) {
func configs(h *wp.Handle) {
wp.InitPipe(h)
h.PushHandler(constraints.PipeMiddleware, constraints.Home,
wp.NewHandleFn(widget.CheckCategory, 100.006, "widget.CheckCategory"))
h.PushHandler(constraints.PipeMiddleware, constraints.Detail,
wp.NewHandleFn(wp.ShowPreComment, 100, "wp.ShowPreComment"),
)
middleware.CommonMiddleware(h)
h.AddActionFilter("bodyClass", calClass)
h.PushCacheGroupHeadScript(constraints.AllScene, "colorScheme-customHeader", 10, colorScheme, customHeader)
components.WidgetArea(h)

View File

@ -57,8 +57,8 @@ func (h *Handle) BodyClass() string {
author := h.Index.Param.Author
user, _ := cache.GetUserByName(h.C, author)
class = append(class, str.Join("author-", number.IntToString(user.Id)))
if user.UserLogin[0] != '%' {
class = append(class, str.Join("author-", user.UserLogin))
if user.DisplayName[0] != '%' {
class = append(class, str.Join("author-", user.DisplayName))
}
case constraints.Detail:

View File

@ -12,7 +12,6 @@ import (
"github.com/fthvgb1/wp-go/helper/slice"
str "github.com/fthvgb1/wp-go/helper/strings"
"github.com/fthvgb1/wp-go/helper/tree"
"net/http"
"strings"
)
@ -235,39 +234,6 @@ func DropdownCategories(h *wp.Handle, args map[string]string, conf map[any]any,
return h.DoActionFilter("wp_dropdown_cats", s.String())
}
func CheckCategory(h *wp.Handle) {
name, ok := parseDropdownCate(h)
if ok {
h.C.Redirect(http.StatusMovedPermanently, fmt.Sprintf("/p/category/%s", name))
h.Abort()
}
}
func parseDropdownCate(h *wp.Handle) (cateName string, r bool) {
cate := wp.GetComponentsArgs[map[string]string](h, widgets.Categories, categoryArgs())
name, ok := cate["{$name}"]
if !ok || name == "" {
return
}
cat := h.C.Query(name)
if cat == "" {
return
}
id := str.ToInteger[uint64](cat, 0)
if id < 1 {
return
}
i, cc := slice.SearchFirst(cache.CategoriesTags(h.C, constraints.Category), func(my models.TermsMy) bool {
return id == my.Terms.TermId
})
if i < 0 {
return
}
r = true
cateName = cc.Name
return
}
func IsCategory(h *wp.Handle) (category models.TermsMy, r bool) {
cate := wp.GetComponentsArgs[map[string]string](h, widgets.Categories, categoryArgs())
name, ok := cate["{$name}"]
@ -292,3 +258,12 @@ func IsCategory(h *wp.Handle) (category models.TermsMy, r bool) {
category = cc
return
}
func CategoryQueryName(h *wp.Handle) string {
cate := wp.GetComponentsArgs[map[string]string](h, widgets.Categories, categoryArgs())
name, ok := cate["{$name}"]
if ok {
return name
}
return ""
}

View File

@ -14,7 +14,6 @@ import (
"github.com/fthvgb1/wp-go/helper/number"
str "github.com/fthvgb1/wp-go/helper/strings"
"github.com/fthvgb1/wp-go/plugin/pagination"
"net/http"
"strings"
"time"
)
@ -28,6 +27,7 @@ type DetailHandle struct {
Post models.Posts
CommentPageEle pagination.Render
TotalRaw int
TotalPage int
}
func NewDetailHandle(handle *Handle) *DetailHandle {
@ -40,21 +40,11 @@ func (d *DetailHandle) BuildDetailData() (err error) {
if err != nil {
return
}
d.Comment()
d.CommentData()
d.ContextPost()
return
}
func ShowPreComment(h *Handle) {
v, ok := cache.NewCommentCache().Get(h.C, h.C.Request.URL.RawQuery)
if ok {
h.C.Writer.Header().Set("Content-Type", "text/html; charset=utf-8")
h.C.Writer.WriteHeader(http.StatusOK)
_, _ = h.C.Writer.Write([]byte(v))
h.Abort()
}
}
func (d *DetailHandle) CheckAndGetPost() (err error) {
id := str.ToInteger[uint64](d.C.Param("id"), 0)
maxId, err := cache.GetMaxPostId(d.C)
@ -88,7 +78,7 @@ func (d *DetailHandle) PasswordProject() {
}
}
}
func (d *DetailHandle) Comment() {
func (d *DetailHandle) CommentData() {
d.ginH["totalCommentNum"] = 0
d.ginH["totalCommentPage"] = 1
d.ginH["commentPageNav"] = ""
@ -109,11 +99,11 @@ func (d *DetailHandle) Comment() {
d.SetErr(err)
return
}
totalPage := number.DivideCeil(topNum, d.Limit)
d.TotalPage = number.DivideCeil(topNum, d.Limit)
if !strings.Contains(d.C.Request.URL.Path, "comment-page") {
defaultCommentsPage := wpconfig.GetOption("default_comments_page")
if order == "desc" && defaultCommentsPage == "oldest" || order == "asc" && defaultCommentsPage == "newest" {
d.C.AddParam("page", number.IntToString(totalPage))
d.C.AddParam("page", number.IntToString(d.TotalPage))
}
}
d.Page = str.ToInteger(d.C.Param("page"), 1)
@ -121,16 +111,17 @@ func (d *DetailHandle) Comment() {
var key string
if pageComments != "1" {
key = number.IntToString(d.Post.Id)
d.Limit = 0
} else {
key = fmt.Sprintf("%d-%d-%d", d.Post.Id, d.Page, d.Limit)
}
d.ginH["page_comments"] = pageComments
d.ginH["totalCommentPage"] = totalPage
if totalPage < d.Page {
d.ginH["totalCommentPage"] = d.TotalPage
if d.TotalPage < d.Page {
d.SetErr(errors.New("curren page above total page"))
return
}
data, err := cachemanager.GetBy[[]uint64]("PostCommentsIds", d.C, key, time.Second, d.Post.Id, d.Page, d.Limit, topNum)
data, err := cache.PostTopLevelCommentIds(d.C, d.Post.Id, d.Page, d.Limit, topNum, order, key)
if err != nil {
d.SetErr(err)
return
@ -163,7 +154,7 @@ func (d *DetailHandle) RenderComment() {
if d.CommentPageEle == nil {
d.CommentPageEle = plugins.TwentyFifteenCommentPagination()
}
if wpconfig.GetOption("page_comments") == "1" {
if wpconfig.GetOption("page_comments") == "1" && d.TotalPage > 1 {
d.ginH["commentPageNav"] = pagination.Paginate(d.CommentPageEle, d.TotalRaw, d.Limit, d.Page, 1, *d.C.Request.URL, d.IsHttps())
}
}

View File

@ -0,0 +1,154 @@
package middleware
import (
"github.com/fthvgb1/wp-go/app/pkg/cache"
"github.com/fthvgb1/wp-go/app/pkg/constraints"
"github.com/fthvgb1/wp-go/app/theme/wp"
"github.com/fthvgb1/wp-go/app/theme/wp/components/widget"
"github.com/fthvgb1/wp-go/cache/reload"
"github.com/fthvgb1/wp-go/helper/maps"
"github.com/fthvgb1/wp-go/helper/number"
str "github.com/fthvgb1/wp-go/helper/strings"
"net/http"
"strconv"
"time"
)
var plainRouteParam = reload.Vars([]Plain{
{
Action: "p",
Param: map[string]string{
"p": "id",
"cpage": "page",
},
Scene: constraints.Detail,
},
{
Scene: constraints.Category,
Fn: func(h *wp.Handle) bool {
c, ok := widget.IsCategory(h)
if !ok {
return false
}
h.C.AddParam("category", c.Name)
h.C.AddParam("page", h.C.Query("paged"))
return true
},
},
{
Scene: constraints.Tag,
Action: "tag",
Param: map[string]string{
"tag": "tag",
"paged": "page",
},
},
{
Scene: constraints.Archive,
Fn: func(h *wp.Handle) bool {
m := h.C.Query("m")
if m == "" {
return false
}
t, err := time.Parse("200601", m)
if err != nil {
return false
}
h.C.AddParam("year", strconv.Itoa(t.Year()))
h.C.AddParam("month", number.IntToString(t.Month()))
h.C.AddParam("page", h.C.Query("paged"))
return true
},
},
{
Scene: constraints.Author,
Fn: func(h *wp.Handle) bool {
u := h.C.Query("author")
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
})
name, ok := users[str.ToInteger[uint64](u, 0)]
if !ok {
return false
}
h.C.AddParam("author", name)
h.C.AddParam("page", h.C.Query("paged"))
return true
},
},
})
func PushExplainRouteParam(explain ...Plain) {
v := plainRouteParam.Load()
v = append(v, explain...)
plainRouteParam.Store(v)
}
type Plain struct {
Action string
Param map[string]string
Scene string
Fn func(h *wp.Handle) bool
}
func MixWithPlain(h *wp.Handle) {
for _, explain := range plainRouteParam.Load() {
if explain.Action == "" && explain.Fn == nil {
continue
}
if explain.Fn != nil {
if !explain.Fn(h) {
continue
}
h.C.Set("inited", false)
if explain.Scene != "" {
h.SetScene(explain.Scene)
}
wp.Run(h, nil)
h.Abort()
return
}
if explain.Scene == "" {
continue
}
action := h.C.Query(explain.Action)
if action == "" {
continue
}
h.SetScene(explain.Scene)
for query, param := range explain.Param {
h.C.AddParam(param, h.C.Query(query))
}
h.C.Set("inited", false)
wp.Run(h, nil)
h.Abort()
return
}
}
func ShowPreComment(h *wp.Handle) {
v, ok := cache.NewCommentCache().Get(h.C, h.C.Request.URL.RawQuery)
if ok {
h.C.Writer.Header().Set("Content-Type", "text/html; charset=utf-8")
h.C.Writer.WriteHeader(http.StatusOK)
_, _ = h.C.Writer.Write([]byte(v))
h.Abort()
}
}
func CommonMiddleware(h *wp.Handle) {
h.PushHandler(constraints.PipeMiddleware, constraints.Home,
wp.NewHandleFn(MixWithPlain, 100, "middleware.MixWithPlain"),
)
h.PushHandler(constraints.PipeMiddleware, constraints.Detail,
wp.NewHandleFn(ShowPreComment, 100, "middleware.ShowPreComment"),
)
}

View File

@ -107,30 +107,32 @@ func Run(h *Handle, conf func(*Handle)) {
if !helper.GetContextVal(h.C, "inited", false) {
InitHandle(conf, h)
}
reload.GetAnyValBys(str.Join("pipeInit-", h.scene), h, func(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) {
var ok bool
hooks := GetFnHook[func(Pipe) (Pipe, bool)]("pipeHook", constraints.AllScene)
hooks = append(hooks, GetFnHook[func(Pipe) (Pipe, bool)]("pipeHook", h.scene)...)
for _, fn := range hooks {
pipe, ok = fn(pipe)
if !ok {
return pipe, false
}
}
return pipe, pipe.Fn != nil
})
slice.SimpleSort(pipes, slice.DESC, func(t Pipe) float64 {
return t.Order
})
reload.GetAnyValBys(str.Join("pipeInit-", h.scene), h, BuildPipeAndHandler)(h)
}
arr := slice.Map(pipes, func(t Pipe) HandlePipeFn[*Handle] {
return t.Fn
})
return HandlePipe(NothingToDo, arr...), true
})(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) {
var ok bool
hooks := GetFnHook[func(Pipe) (Pipe, bool)]("pipeHook", constraints.AllScene)
hooks = append(hooks, GetFnHook[func(Pipe) (Pipe, bool)]("pipeHook", h.scene)...)
for _, fn := range hooks {
pipe, ok = fn(pipe)
if !ok {
return pipe, false
}
}
return pipe, pipe.Fn != nil
})
slice.SimpleSort(pipes, slice.DESC, func(t Pipe) float64 {
return t.Order
})
arr := slice.Map(pipes, func(t Pipe) HandlePipeFn[*Handle] {
return t.Fn
})
return HandlePipe(NothingToDo, arr...), true
}
func MiddlewareKey(h *Handle, pipScene string) string {

View File

@ -196,6 +196,10 @@ func GetAnyValBys[T, A any](namespace string, a A, fn func(A) (T, bool), args ..
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
func Vars[T any](defaults T, args ...any) *safety.Var[T] {
ss := safety.NewVar(defaults)
ord, name := parseArgs(args...)
@ -220,6 +224,11 @@ func parseArgs(a ...any) (ord float64, name string) {
}
return ord, name
}
// VarsBy
//
// args same as Push
// if give a name, then can be flushed by calls FlushAnyVal
func VarsBy[T any](fn func() T, args ...any) *safety.Var[T] {
ss := safety.NewVar(fn())
ord, name := parseArgs(args...)
@ -252,6 +261,9 @@ func SafeMap[K comparable, T any](args ...any) *safety.Map[K, T] {
return m
}
// Push the func that will be call whenever Reload called
//
// if give a name, then can be flushed by calls FlushAnyVal
func Push(fn func(), a ...any) {
ord, name := parseArgs(a...)
calls.Append(queue{fn, ord, name})