diff --git a/helper/number/number.go b/helper/number/number.go index e493eae..6be801b 100644 --- a/helper/number/number.go +++ b/helper/number/number.go @@ -5,6 +5,7 @@ package number import ( "fmt" "golang.org/x/exp/constraints" + "math" "math/rand" ) @@ -86,3 +87,7 @@ func Mul[T constraints.Integer | constraints.Float](i, j T) T { func Divide[T constraints.Integer | constraints.Float](i, j T) T { return i / j } + +func CalTotalPage[T constraints.Integer](totalRows, size T) T { + return T(math.Ceil(float64(totalRows) / float64(size))) +} diff --git a/helper/number/number_test.go b/helper/number/number_test.go index 4cfb19f..2f1602e 100644 --- a/helper/number/number_test.go +++ b/helper/number/number_test.go @@ -219,3 +219,34 @@ func TestAbs(t *testing.T) { }) } } + +func TestCalTotalPage(t *testing.T) { + type args[T constraints.Integer] struct { + totalRows T + size T + } + type testCase[T constraints.Integer] struct { + name string + args args[T] + want T + } + tests := []testCase[int]{ + { + name: "t1", + args: args[int]{5, 2}, + want: 3, + }, + { + name: "t1", + args: args[int]{4, 2}, + want: 2, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := CalTotalPage(tt.args.totalRows, tt.args.size); got != tt.want { + t.Errorf("CalTotalPage() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/internal/actions/detail.go b/internal/actions/detail.go index 2c158d7..2f63e17 100644 --- a/internal/actions/detail.go +++ b/internal/actions/detail.go @@ -5,6 +5,7 @@ import ( "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/constraints" "github.com/fthvgb1/wp-go/internal/pkg/logs" "github.com/fthvgb1/wp-go/internal/pkg/models" "github.com/fthvgb1/wp-go/internal/plugins" @@ -21,7 +22,7 @@ func Detail(c *gin.Context) { var post models.Posts recent := slice.Map(cache.RecentPosts(c, 5), common.ProjectTitle) archive := cache.Archives(c) - categoryItems := cache.CategoriesTags(c, plugins.Category) + categoryItems := cache.CategoriesTags(c, constraints.Category) recentComments := cache.RecentComments(c, 5) var ginH = gin.H{ "title": wpconfig.Options.Value("blogname"), @@ -32,7 +33,7 @@ func Detail(c *gin.Context) { "post": post, } isApproveComment := false - stats := plugins.Ok + stats := constraints.Ok pw := sessions.Default(c).Get("post_password") defer func() { @@ -40,7 +41,7 @@ func Detail(c *gin.Context) { if err != nil { code = http.StatusNotFound c.Error(err) - stats = plugins.Error + stats = constraints.ParamError return } if isApproveComment == true { @@ -52,7 +53,7 @@ func Detail(c *gin.Context) { C: c, GinH: ginH, Password: "", - Scene: plugins.Detail, + Scene: constraints.Detail, Code: code, Stats: stats, }) @@ -62,12 +63,12 @@ func Detail(c *gin.Context) { maxId, err := cache.GetMaxPostId(c) logs.ErrPrintln(err, "get max post id") if id > maxId || id <= 0 || err != nil { - stats = plugins.Empty404 + stats = constraints.Error404 return } post, err = cache.GetPostById(c, id) if post.Id == 0 || err != nil || post.PostStatus != "publish" { - stats = plugins.Empty404 + stats = constraints.Error404 return } showComment := false @@ -102,5 +103,5 @@ func Detail(c *gin.Context) { ginH["maxDep"] = d ginH["next"] = next ginH["user"] = user - ginH["scene"] = plugins.Detail + ginH["scene"] = constraints.Detail } diff --git a/internal/actions/index.go b/internal/actions/index.go index 608f803..9967e27 100644 --- a/internal/actions/index.go +++ b/internal/actions/index.go @@ -1,302 +1,21 @@ package actions import ( - "errors" - "fmt" - "github.com/fthvgb1/wp-go/helper/maps" - "github.com/fthvgb1/wp-go/helper/number" - "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/config" - "github.com/fthvgb1/wp-go/internal/pkg/dao" - "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/pkg/constraints" "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" - "github.com/gin-contrib/sessions" "github.com/gin-gonic/gin" - "math" "net/http" - "strconv" - "strings" - "sync/atomic" - "time" ) -type indexHandle struct { - c *gin.Context - session sessions.Session - page int - pageSize int - title string - titleL string - titleR string - search string - author string - totalPage int - category string - categoryType string - where model.SqlBuilder - orderBy string - order string - join model.SqlBuilder - postType []any - postStatus []any - header string - paginationStep int - scene int - stats int -} - -func newIndexHandle(ctx *gin.Context) *indexHandle { - size := str.ToInteger(wpconfig.Options.Value("posts_per_page"), 10) - return &indexHandle{ - c: ctx, - session: sessions.Default(ctx), - page: 1, - pageSize: size, - paginationStep: 1, - titleL: wpconfig.Options.Value("blogname"), - titleR: wpconfig.Options.Value("blogdescription"), - where: model.SqlBuilder{ - {"post_type", "in", ""}, - {"post_status", "in", ""}, - }, - orderBy: "post_date", - join: model.SqlBuilder{}, - postType: []any{"post"}, - postStatus: []any{"publish"}, - scene: plugins.Home, - stats: plugins.Ok, - } -} - -var months = slice.SimpleToMap(number.Range(1, 12, 1), func(v int) int { - return v -}) - -func (h *indexHandle) setTitleLR(l, r string) { - h.titleL = l - h.titleR = r -} - -func (h *indexHandle) getTitle() string { - h.title = fmt.Sprintf("%s-%s", h.titleL, h.titleR) - return h.title -} - -func (h *indexHandle) getSearchKey() string { - return fmt.Sprintf("action:%s|%s|%s|%s|%s|%s|%d|%d", h.author, h.search, h.orderBy, h.order, h.category, h.categoryType, h.page, h.pageSize) -} - -var orders = map[string]struct{}{"asc": {}, "desc": {}} - -func (h *indexHandle) parseParams() (err error) { - h.order = h.c.Query("order") - if !maps.IsExists(orders, h.order) { - order := config.GetConfig().PostOrder - h.order = "asc" - if order != "" && maps.IsExists(orders, order) { - h.order = order - } - } - year := h.c.Param("year") - if year != "" { - y := str.ToInteger(year, -1) - if y > time.Now().Year() || y <= 1970 { - return errors.New(str.Join("year err : ", year)) - } - h.where = append(h.where, []string{ - "year(post_date)", year, +func Index(scene int) func(*gin.Context) { + return func(ctx *gin.Context) { + theme.Hook(theme.GetTemplateName(), common.Handle{ + C: ctx, + GinH: gin.H{}, + Scene: scene, + Code: http.StatusOK, + Stats: constraints.Ok, }) } - month := h.c.Param("month") - if month != "" { - m := str.ToInteger(month, -1) - if !maps.IsExists(months, m) { - return errors.New(str.Join("months err ", month)) - } - - h.where = append(h.where, []string{ - "month(post_date)", month, - }) - ss := fmt.Sprintf("%s年%s月", year, strings.TrimLeft(month, "0")) - h.header = fmt.Sprintf("月度归档: %s", ss) - h.setTitleLR(ss, wpconfig.Options.Value("blogname")) - h.scene = plugins.Archive - } - category := h.c.Param("category") - if category != "" { - h.scene = plugins.Category - if !maps.IsExists(cache.AllCategoryTagsNames(h.c, plugins.Category), category) { - return errors.New(str.Join("not exists category ", category)) - } - h.categoryType = "category" - h.header = fmt.Sprintf("分类: %s", category) - h.category = category - } - tag := h.c.Param("tag") - if tag != "" { - h.scene = plugins.Tag - if !maps.IsExists(cache.AllCategoryTagsNames(h.c, plugins.Tag), tag) { - return errors.New(str.Join("not exists tag ", tag)) - } - h.categoryType = "post_tag" - h.header = fmt.Sprintf("标签: %s", tag) - h.category = tag - } - - username := h.c.Param("author") - if username != "" { - allUsername, er := cache.GetAllUsername(h.c) - if er != nil { - err = er - return - } - if !maps.IsExists(allUsername, username) { - err = errors.New(str.Join("user ", username, " is not exists")) - return - } - user, er := cache.GetUserByName(h.c, username) - if er != nil { - err = er - return - } - h.author = username - h.where = append(h.where, []string{ - "post_author", "=", strconv.FormatUint(user.Id, 10), "int", - }) - } - if h.category != "" { - h.where = append(h.where, []string{ - "d.name", h.category, - }, []string{"taxonomy", h.categoryType}) - h.join = append(h.join, []string{ - "a", "left join", "wp_term_relationships b", "a.Id=b.object_id", - }, []string{ - "left join", "wp_term_taxonomy c", "b.term_taxonomy_id=c.term_taxonomy_id", - }, []string{ - "left join", "wp_terms d", "c.term_id=d.term_id", - }) - h.setTitleLR(h.category, wpconfig.Options.Value("blogname")) - } - s, ok := h.c.GetQuery("s") - if ok { - h.scene = plugins.Search - } - if s != "" && strings.Replace(s, " ", "", -1) != "" { - q := str.Join("%", s, "%") - h.where = append(h.where, []string{ - "and", "post_title", "like", q, "", - "or", "post_content", "like", q, "", - "or", "post_excerpt", "like", q, "", - }, []string{"post_password", ""}) - h.postType = append(h.postType, "page", "attachment") - h.header = fmt.Sprintf("%s的搜索结果", s) - h.setTitleLR(str.Join(`"`, s, `"`, "的搜索结果"), wpconfig.Options.Value("blogname")) - h.search = s - h.scene = plugins.Search - } - h.page = str.ToInteger(h.c.Param("page"), 1) - total := int(atomic.LoadInt64(&dao.TotalRaw)) - if total > 0 && total < (h.page-1)*h.pageSize { - h.page = 1 - } - if h.page > 1 && (h.category != "" || h.search != "" || month != "") { - h.setTitleLR(fmt.Sprintf("%s-第%d页", h.titleL, h.page), wpconfig.Options.Value("blogname")) - } - return -} - -func (h *indexHandle) getTotalPage(totalRaws int) int { - h.totalPage = int(math.Ceil(float64(totalRaws) / float64(h.pageSize))) - return h.totalPage -} - -func Index(c *gin.Context) { - h := newIndexHandle(c) - var posts []models.Posts - var totalRaw int - var err error - archive := cache.Archives(c) - recent := slice.Map(cache.RecentPosts(c, 5), common.ProjectTitle) - categoryItems := cache.CategoriesTags(c, plugins.Category) - recentComments := cache.RecentComments(c, 5) - ginH := gin.H{ - "err": err, - "recentPosts": recent, - "archives": archive, - "categories": categoryItems, - "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.stats == plugins.InternalErr { - code = http.StatusInternalServerError - c.Error(err) - return - } - c.Error(err) - h.stats = plugins.Error - } - t := theme.GetTemplateName() - 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 { - return - } - ginH["title"] = h.getTitle() - ginH["search"] = h.search - ginH["header"] = h.header - if c.Param("month") != "" { - posts, totalRaw, err = cache.GetMonthPostIds(c, c.Param("year"), c.Param("month"), h.page, h.pageSize, h.order) - if err != nil { - return - } - } else if h.search != "" { - posts, totalRaw, err = cache.SearchPost(c, h.getSearchKey(), c, h.where, h.page, h.pageSize, model.SqlBuilder{{h.orderBy, h.order}}, h.join, h.postType, h.postStatus) - } else { - 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.stats = plugins.Error - logs.ErrPrintln(err, "获取数据错误") - return - } - - if len(posts) < 1 && h.category != "" { - h.titleL = "未找到页面" - h.stats = plugins.Empty404 - } - q := c.Request.URL.Query().Encode() - if q != "" { - q = fmt.Sprintf("?%s", q) - } - ginH["posts"] = posts - 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/cmd/route/route.go b/internal/cmd/route/route.go index 78ff6a5..a2f1f49 100644 --- a/internal/cmd/route/route.go +++ b/internal/cmd/route/route.go @@ -4,6 +4,7 @@ import ( "github.com/fthvgb1/wp-go/internal/actions" "github.com/fthvgb1/wp-go/internal/middleware" "github.com/fthvgb1/wp-go/internal/pkg/config" + "github.com/fthvgb1/wp-go/internal/pkg/constraints" "github.com/fthvgb1/wp-go/internal/static" "github.com/fthvgb1/wp-go/internal/theme" "github.com/gin-contrib/gzip" @@ -61,16 +62,16 @@ func SetupRouter() (*gin.Engine, func()) { store := cookie.NewStore([]byte("secret")) r.Use(sessions.Sessions("go-wp", store)) sl, slRload := middleware.SearchLimit(c.SingleIpSearchNum) - r.GET("/", sl, actions.Index) - r.GET("/page/:page", actions.Index) - r.GET("/p/category/:category", actions.Index) - r.GET("/p/category/:category/page/:page", actions.Index) - r.GET("/p/tag/:tag", actions.Index) - r.GET("/p/tag/:tag/page/:page", actions.Index) - r.GET("/p/date/:year/:month", actions.Index) - r.GET("/p/date/:year/:month/page/:page", actions.Index) - r.GET("/p/author/:author", actions.Index) - r.GET("/p/author/:author/page/:page", actions.Index) + r.GET("/", sl, actions.Index(constraints.Home)) + r.GET("/page/:page", actions.Index(constraints.Home)) + r.GET("/p/category/:category", actions.Index(constraints.Category)) + r.GET("/p/category/:category/page/:page", actions.Index(constraints.Category)) + r.GET("/p/tag/:tag", actions.Index(constraints.Tag)) + r.GET("/p/tag/:tag/page/:page", actions.Index(constraints.Tag)) + r.GET("/p/date/:year/:month", actions.Index(constraints.Archive)) + r.GET("/p/date/:year/:month/page/:page", actions.Index(constraints.Archive)) + r.GET("/p/author/:author", actions.Index(constraints.Author)) + r.GET("/p/author/:author/page/:page", actions.Index(constraints.Author)) r.POST("/login", actions.Login) r.GET("/p/:id", actions.Detail) r.GET("/p/:id/feed", actions.PostFeed) diff --git a/internal/pkg/constraints/plugins.go b/internal/pkg/constraints/plugins.go index 6da295d..19b5f37 100644 --- a/internal/pkg/constraints/plugins.go +++ b/internal/pkg/constraints/plugins.go @@ -10,7 +10,7 @@ const ( Detail Ok - Empty404 + Error404 ParamError InternalErr ) diff --git a/internal/theme/common/common.go b/internal/theme/common/common.go index 3445431..922a8f3 100644 --- a/internal/theme/common/common.go +++ b/internal/theme/common/common.go @@ -24,15 +24,15 @@ type Handle struct { Stats int } -func (h Handle) Detail() { +func (h *Handle) Detail() { } -func (h Handle) Index() { +func (h *Handle) Index() { } -func (h Handle) ExecListPagePlugin(m map[string]Plugin[models.Posts], calls ...func(*models.Posts)) { +func (h *Handle) ExecListPagePlugin(m map[string]Plugin[models.Posts], calls ...func(*models.Posts)) { pluginConf := config.GetConfig().ListPagePlugins @@ -45,14 +45,14 @@ func (h Handle) ExecListPagePlugin(m map[string]Plugin[models.Posts], calls ...f } } -/*func (h Handle) Pagination(paginate pagination) { +/*func (h *Handle) Pagination(paginate pagination) { }*/ type Fn[T any] func(T) T -type Plugin[T any] func(next Fn[T], h Handle, t 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] { +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) @@ -94,7 +94,7 @@ func GetListPostPlugins(name []string, m map[string]Plugin[models.Posts]) []Plug } // PasswordProject 标题和内容密码保护 -func PasswordProject(next Fn[models.Posts], h Handle, post models.Posts) (r models.Posts) { +func PasswordProject(next Fn[models.Posts], h *Handle, post models.Posts) (r models.Posts) { r = post if post.PostPassword != "" { plugins.PasswordProjectTitle(&r) @@ -115,7 +115,7 @@ func ProjectTitle(t models.Posts) models.Posts { } // Digest 生成摘要 -func Digest(next Fn[models.Posts], h Handle, post models.Posts) models.Posts { +func Digest(next Fn[models.Posts], h *Handle, post models.Posts) models.Posts { if post.PostExcerpt != "" { plugins.PostExcerpt(&post) } else { diff --git a/internal/theme/common/index.go b/internal/theme/common/index.go new file mode 100644 index 0000000..16ebc4f --- /dev/null +++ b/internal/theme/common/index.go @@ -0,0 +1,308 @@ +package common + +import ( + "database/sql" + "errors" + "fmt" + "github.com/fthvgb1/wp-go/helper/maps" + "github.com/fthvgb1/wp-go/helper/number" + "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/config" + "github.com/fthvgb1/wp-go/internal/pkg/constraints" + "github.com/fthvgb1/wp-go/internal/pkg/dao" + "github.com/fthvgb1/wp-go/internal/pkg/models" + "github.com/fthvgb1/wp-go/internal/wpconfig" + "github.com/fthvgb1/wp-go/model" + "github.com/fthvgb1/wp-go/plugin/pagination" + "github.com/gin-gonic/gin" + "net/http" + "strconv" + "strings" + "sync/atomic" + "time" +) + +type IndexParams struct { + c *gin.Context + Page int + PageSize int + Title string + titleL string + titleR string + search string + author string + totalPage int + category string + categoryType string + Where model.SqlBuilder + OrderBy string + Order string + Month string + Year string + Join model.SqlBuilder + PostType []any + PostStatus []any + header string + PaginationStep int + scene int + stats int + CacheKey string + blogName string +} + +var months = slice.SimpleToMap(number.Range(1, 12, 1), func(v int) int { + return v +}) + +var orders = map[string]struct{}{"asc": {}, "desc": {}} + +func (i *IndexParams) setTitleLR(l, r string) { + i.titleL = l + i.titleR = r +} + +func (i *IndexParams) getTitle() string { + i.Title = fmt.Sprintf("%s-%s", i.titleL, i.titleR) + return i.Title +} + +func (i *IndexParams) getSearchKey() string { + return fmt.Sprintf("action:%s|%s|%s|%s|%s|%s|%d|%d", i.author, i.search, i.OrderBy, i.Order, i.category, i.categoryType, i.Page, i.PageSize) +} + +func newIndexHandle(ctx *gin.Context) *IndexParams { + blogName := wpconfig.Options.Value("blogname") + size := str.ToInteger(wpconfig.Options.Value("posts_per_page"), 10) + return &IndexParams{ + c: ctx, + Page: 1, + PageSize: size, + PaginationStep: number.Max(1, config.GetConfig().PaginationStep), + titleL: blogName, + titleR: wpconfig.Options.Value("blogdescription"), + Where: model.SqlBuilder{ + {"post_type", "in", ""}, + {"post_status", "in", ""}, + }, + OrderBy: "post_date", + Join: model.SqlBuilder{}, + PostType: []any{"post"}, + PostStatus: []any{"publish"}, + scene: constraints.Home, + stats: constraints.Ok, + blogName: wpconfig.Options.Value("blogname"), + } +} + +func (i *IndexParams) ParseSearch() { + s := i.c.Query("s") + if s != "" && strings.Replace(s, " ", "", -1) != "" { + q := str.Join("%", s, "%") + i.Where = append(i.Where, []string{ + "and", "post_title", "like", q, "", + "or", "post_content", "like", q, "", + "or", "post_excerpt", "like", q, "", + }, []string{"post_password", ""}) + i.PostType = append(i.PostType, "Page", "attachment") + i.header = fmt.Sprintf("%s的搜索结果", s) + i.setTitleLR(str.Join(`"`, s, `"`, "的搜索结果"), i.blogName) + i.search = s + i.scene = constraints.Search + } +} +func (i *IndexParams) ParseArchive() error { + year := i.c.Param("year") + if year != "" { + y := str.ToInteger(year, -1) + if y > time.Now().Year() || y <= 1970 { + return errors.New(str.Join("year err : ", year)) + } + i.Where = append(i.Where, []string{ + "year(post_date)", year, + }) + i.Year = year + } + month := i.c.Param("month") + if month != "" { + m := str.ToInteger(month, -1) + if !maps.IsExists(months, m) { + return errors.New(str.Join("months err ", month)) + } + + i.Where = append(i.Where, []string{ + "month(post_date)", month, + }) + ss := fmt.Sprintf("%s年%s月", year, strings.TrimLeft(month, "0")) + i.header = fmt.Sprintf("月度归档: %s", ss) + i.setTitleLR(ss, i.blogName) + i.scene = constraints.Archive + i.Month = month + } + return nil +} + +func (i *IndexParams) ParseCategory() error { + category := i.c.Param("category") + if category != "" { + i.scene = constraints.Category + if !maps.IsExists(cache.AllCategoryTagsNames(i.c, constraints.Category), category) { + return errors.New(str.Join("not exists category ", category)) + } + i.categoryType = "category" + i.header = fmt.Sprintf("分类: %s", category) + i.category = category + i.CategoryCondition() + } + return nil +} +func (i *IndexParams) ParseTag() error { + tag := i.c.Param("tag") + if tag != "" { + i.scene = constraints.Tag + if !maps.IsExists(cache.AllCategoryTagsNames(i.c, constraints.Tag), tag) { + return errors.New(str.Join("not exists tag ", tag)) + } + i.categoryType = "post_tag" + i.header = fmt.Sprintf("标签: %s", tag) + i.category = tag + i.CategoryCondition() + } + return nil +} + +func (i *IndexParams) CategoryCondition() { + if i.category != "" { + i.Where = append(i.Where, []string{ + "d.name", i.category, + }, []string{"taxonomy", i.categoryType}) + i.Join = append(i.Join, []string{ + "a", "left Join", "wp_term_relationships b", "a.Id=b.object_id", + }, []string{ + "left Join", "wp_term_taxonomy c", "b.term_taxonomy_id=c.term_taxonomy_id", + }, []string{ + "left Join", "wp_terms d", "c.term_id=d.term_id", + }) + i.setTitleLR(i.category, i.blogName) + } +} +func (i *IndexParams) ParseAuthor() (err error) { + username := i.c.Param("author") + if username != "" { + allUsername, er := cache.GetAllUsername(i.c) + if err != nil { + err = er + return + } + if !maps.IsExists(allUsername, username) { + err = errors.New(str.Join("user ", username, " is not exists")) + return + } + user, er := cache.GetUserByName(i.c, username) + if er != nil { + return + } + i.author = username + i.Where = append(i.Where, []string{ + "post_author", "=", strconv.FormatUint(user.Id, 10), "int", + }) + } + return +} + +func (i *IndexParams) parseParams() { + i.Order = i.c.Query("Order") + if !maps.IsExists(orders, i.Order) { + order := config.GetConfig().PostOrder + i.Order = "asc" + if order != "" && maps.IsExists(orders, order) { + i.Order = order + } + } + + i.Page = str.ToInteger(i.c.Param("page"), 1) + total := int(atomic.LoadInt64(&dao.TotalRaw)) + if total > 0 && total < (i.Page-1)*i.PageSize { + i.Page = 1 + } + if i.Page > 1 && (i.category != "" || i.search != "" || i.Month != "") { + i.setTitleLR(fmt.Sprintf("%s-第%d页", i.titleL, i.Page), i.blogName) + } + return +} + +func (h *Handle) ParseIndex() (i *IndexParams, err error) { + i = newIndexHandle(h.C) + switch h.Scene { + case constraints.Home, constraints.Search: + i.ParseSearch() + case constraints.Category: + err = i.ParseCategory() + case constraints.Tag: + err = i.ParseTag() + case constraints.Archive: + err = i.ParseArchive() + case constraints.Author: + err = i.ParseAuthor() + } + if err != nil { + h.Stats = constraints.ParamError + return + } + i.CacheKey = i.getSearchKey() + i.parseParams() + h.GinH["title"] = i.getTitle() + h.GinH["search"] = i.search + h.GinH["header"] = i.header + return +} + +func (h *Handle) GetIndexData(i *IndexParams) (posts []models.Posts, totalRaw int, err error) { + + switch h.Scene { + case constraints.Home, constraints.Category, constraints.Tag, constraints.Author: + + posts, totalRaw, err = cache.PostLists(h.C, i.CacheKey, h.C, i.Where, i.Page, i.PageSize, + model.SqlBuilder{{i.OrderBy, i.Order}}, i.Join, i.PostType, i.PostStatus) + + case constraints.Search: + + posts, totalRaw, err = cache.SearchPost(h.C, i.CacheKey, h.C, i.Where, i.Page, i.PageSize, + model.SqlBuilder{{i.OrderBy, i.Order}}, i.Join, i.PostType, i.PostStatus) + + case constraints.Archive: + + posts, totalRaw, err = cache.GetMonthPostIds(h.C, i.Year, i.Month, i.Page, i.PageSize, i.Order) + + } + return + +} + +func (h *Handle) Indexs() (err error) { + i, err := h.ParseIndex() + if err != nil { + h.Stats = constraints.ParamError + h.Code = http.StatusNotFound + return + } + posts, totalRows, err := h.GetIndexData(i) + if err != nil && err != sql.ErrNoRows { + h.Scene = constraints.InternalErr + h.Code = http.StatusInternalServerError + return + } + pw := h.Session.Get("post_password") + if pw != nil { + h.Password = pw.(string) + } + h.GinH["posts"] = posts + h.GinH["totalPage"] = number.CalTotalPage(totalRows, i.PageSize) + q := h.C.Request.URL.Query().Encode() + if q != "" { + q = fmt.Sprintf("?%s", q) + } + h.GinH["pagination"] = pagination.NewParsePagination(totalRows, i.PageSize, i.Page, i.PaginationStep, q, h.C.Request.URL.Path) + return +} diff --git a/internal/theme/common/widgetareadata.go b/internal/theme/common/widgetareadata.go new file mode 100644 index 0000000..7181ea7 --- /dev/null +++ b/internal/theme/common/widgetareadata.go @@ -0,0 +1,14 @@ +package common + +import ( + "github.com/fthvgb1/wp-go/helper/slice" + "github.com/fthvgb1/wp-go/internal/pkg/cache" + "github.com/fthvgb1/wp-go/internal/pkg/constraints" +) + +func (h *Handle) WidgetAreaData() { + h.GinH["archives"] = cache.Archives(h.C) + h.GinH["recentPosts"] = slice.Map(cache.RecentPosts(h.C, 5), ProjectTitle) + h.GinH["categories"] = cache.CategoriesTags(h.C, constraints.Category) + h.GinH["recentComments"] = cache.RecentComments(h.C, 5) +} diff --git a/internal/theme/twentyfifteen/twentyfifteen.go b/internal/theme/twentyfifteen/twentyfifteen.go index 0d6ca2b..7c65657 100644 --- a/internal/theme/twentyfifteen/twentyfifteen.go +++ b/internal/theme/twentyfifteen/twentyfifteen.go @@ -7,6 +7,7 @@ import ( "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-contrib/sessions" ) const ThemeName = "twentyfifteen" @@ -16,13 +17,15 @@ type handle struct { templ string } -func Hook(h2 common.Handle) { +func Hook(cHandle common.Handle) { h := handle{ - Handle: h2, + Handle: cHandle, templ: "twentyfifteen/posts/index.gohtml", } - //h.GinH["HeaderImage"] = h.getHeaderImage(h.C) - if h.Stats == constraints.Empty404 { + h.WidgetAreaData() + h.Session = sessions.Default(h.C) + + if h.Stats == constraints.Error404 { h.C.HTML(h.Code, h.templ, h.GinH) return } @@ -36,17 +39,17 @@ func Hook(h2 common.Handle) { var plugin = common.ListPostPlugins() func (h handle) Index() { - if h.Stats != constraints.Empty404 { - - h.ExecListPagePlugin(plugin) - - page, ok := maps.GetStrMapAnyVal[pagination.ParsePagination](h.GinH, "pagination") - if ok { - h.GinH["pagination"] = pagination.Paginate(plugins.TwentyFifteenPagination(), page) - } + err := h.Indexs() + if err != nil { + h.C.HTML(h.Code, h.templ, h.GinH) + return } - //h.GinH["bodyClass"] = h.bodyClass() + h.ExecListPagePlugin(plugin) + page, ok := maps.GetStrMapAnyVal[pagination.ParsePagination](h.GinH, "pagination") + if ok { + h.GinH["pagination"] = pagination.Paginate(plugins.TwentyFifteenPagination(), page) + } h.C.HTML(h.Code, h.templ, h.GinH) } diff --git a/internal/theme/twentyseventeen/twentyseventeen.go b/internal/theme/twentyseventeen/twentyseventeen.go index c117619..5324825 100644 --- a/internal/theme/twentyseventeen/twentyseventeen.go +++ b/internal/theme/twentyseventeen/twentyseventeen.go @@ -12,6 +12,7 @@ import ( "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-contrib/sessions" "github.com/gin-gonic/gin" "strings" ) @@ -38,6 +39,8 @@ func Hook(cHandle common.Handle) { Handle: cHandle, templ: "twentyseventeen/posts/index.gohtml", } + h.WidgetAreaData() + h.Session = sessions.Default(h.C) h.GinH["HeaderImage"] = h.getHeaderImage(h.C) if h.Scene == constraints.Detail { h.Detail() @@ -52,23 +55,25 @@ var pluginFns = func() map[string]common.Plugin[models.Posts] { }) }() -func (h handle) Index() { - if h.Stats != constraints.Empty404 { - h.ExecListPagePlugin(pluginFns) - page, ok := maps.GetStrMapAnyVal[pagination.ParsePagination](h.GinH, "pagination") - if ok { - h.GinH["pagination"] = pagination.Paginate(paginate, page) - } - } - +func (h *handle) Index() { + err := h.Indexs() h.GinH["bodyClass"] = h.bodyClass() + if err != nil { + h.C.HTML(h.Code, h.templ, h.GinH) + return + } + h.ExecListPagePlugin(pluginFns) + page, ok := maps.GetStrMapAnyVal[pagination.ParsePagination](h.GinH, "pagination") + if ok { + h.GinH["pagination"] = pagination.Paginate(paginate, page) + } h.C.HTML(h.Code, h.templ, h.GinH) } -func (h handle) Detail() { +func (h *handle) Detail() { post := h.GinH["post"].(models.Posts) h.GinH["bodyClass"] = h.bodyClass() - if h.Stats == constraints.Empty404 { + if h.Stats == constraints.Error404 { h.C.HTML(h.Code, h.templ, h.GinH) return } @@ -110,7 +115,7 @@ func (c comment) FormatLi(ctx *gin.Context, m models.Comments, depth int, isTls return plugins.FormatLi(templ, ctx, m, depth, isTls, eo, parent) } -func postThumbnail(next common.Fn[models.Posts], h common.Handle, t models.Posts) models.Posts { +func postThumbnail(next common.Fn[models.Posts], h *common.Handle, t models.Posts) models.Posts { if t.Thumbnail.Path != "" { t.Thumbnail.Sizes = "(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px" if h.Scene == constraints.Detail { @@ -120,7 +125,7 @@ func postThumbnail(next common.Fn[models.Posts], h common.Handle, t models.Posts return next(t) } -func (h handle) getHeaderImage(c *gin.Context) (r models.PostThumbnail) { +func (h *handle) getHeaderImage(c *gin.Context) (r models.PostThumbnail) { r.Path = "/wp-content/themes/twentyseventeen/assets/images/header.jpg" r.Width = 2000 r.Height = 1200 @@ -135,9 +140,9 @@ func (h handle) getHeaderImage(c *gin.Context) (r models.PostThumbnail) { return } -func (h handle) bodyClass() string { +func (h *handle) bodyClass() string { s := "" - if h.Stats == constraints.Empty404 { + if constraints.Ok != h.Stats { return "error404" } switch h.Scene {