diff --git a/actions/common/common.go b/actions/common/common.go index cdaac6d..7cf012c 100644 --- a/actions/common/common.go +++ b/actions/common/common.go @@ -3,8 +3,77 @@ package common import ( "fmt" "github/fthvgb1/wp-go/models" + "strings" + "sync" ) +var PostsCache sync.Map + +func GetPostFromCache(Id uint64) (r models.WpPosts) { + p, ok := PostsCache.Load(Id) + if ok { + r = *p.(*models.WpPosts) + } + return +} + +func QueryAndSetPostCache(postIds []models.WpPosts) (err error) { + var all []uint64 + var needQuery []interface{} + for _, wpPosts := range postIds { + all = append(all, wpPosts.Id) + if _, ok := PostsCache.Load(wpPosts.Id); !ok { + needQuery = append(needQuery, wpPosts.Id) + } + } + if len(needQuery) > 0 { + rawPosts, er := models.Find[models.WpPosts](models.SqlBuilder{{ + "Id", "in", "", + }}, "a.*,ifnull(d.name,'') category_name,ifnull(taxonomy,'') `taxonomy`", "", nil, models.SqlBuilder{{ + "a", "left join", "wp_term_relationships b", "a.Id=b.object_id", + }, { + "left join", "wp_term_taxonomy c", "b.term_taxonomy_id=c.term_taxonomy_id", + }, { + "left join", "wp_terms d", "c.term_id=d.term_id", + }}, 0, needQuery) + if er != nil { + err = er + return + } + postsMap := make(map[uint64]*models.WpPosts) + for i, post := range rawPosts { + v, ok := postsMap[post.Id] + if !ok { + v = &rawPosts[i] + } + if post.Taxonomy == "category" { + v.Categories = append(v.Categories, post.CategoryName) + } else if post.Taxonomy == "post_tag" { + v.Tags = append(v.Tags, post.CategoryName) + } + postsMap[post.Id] = v + } + for _, pp := range postsMap { + if len(pp.Categories) > 0 { + t := make([]string, 0, len(pp.Categories)) + for _, cat := range pp.Categories { + t = append(t, fmt.Sprintf(`%s`, cat, cat)) + } + pp.CategoriesHtml = strings.Join(t, "、") + } + if len(pp.Tags) > 0 { + t := make([]string, 0, len(pp.Tags)) + for _, cat := range pp.Tags { + t = append(t, fmt.Sprintf(``, cat, cat)) + } + pp.TagsHtml = strings.Join(t, "、") + } + PostsCache.Store(pp.Id, pp) + } + } + return +} + func Archives() (r []models.PostArchive, err error) { r, err = models.Find[models.PostArchive](models.SqlBuilder{ {"post_type", "post"}, {"post_status", "publish"}, @@ -37,13 +106,21 @@ func RecentPosts() (r []models.WpPosts, err error) { r, err = models.Find[models.WpPosts](models.SqlBuilder{{ "post_type", "post", }, {"post_status", "publish"}}, "ID,post_title,post_password", "", models.SqlBuilder{{"post_date", "desc"}}, nil, 5) + for i, post := range r { + if post.PostPassword != "" { + PasswordProjectTitle(&r[i]) + } + } return } -func PasswdProject(post *models.WpPosts) { - if post.PostTitle != "" { +func PasswordProjectTitle(post *models.WpPosts) { + if post.PostPassword != "" { post.PostTitle = fmt.Sprintf("密码保护:%s", post.PostTitle) } +} + +func PasswdProjectContent(post *models.WpPosts) { if post.PostContent != "" { format := `
diff --git a/actions/detail.go b/actions/detail.go index 79274e2..5176927 100644 --- a/actions/detail.go +++ b/actions/detail.go @@ -1,7 +1,90 @@ package actions -import "github.com/gin-gonic/gin" +import ( + "fmt" + "github.com/gin-contrib/sessions" + "github.com/gin-gonic/gin" + "github/fthvgb1/wp-go/actions/common" + "github/fthvgb1/wp-go/models" + "net/http" + "strconv" +) func Detail(c *gin.Context) { + id := c.Param("id") + var h = gin.H{} + var err error + defer func() { + c.HTML(http.StatusOK, "detail", h) + if err != nil { + c.Error(err) + } + }() + Id := 0 + if id != "" { + Id, err = strconv.Atoi(id) + if err != nil { + return + } + } + ID := uint64(Id) + post := common.GetPostFromCache(ID) + if post.Id == 0 { + er := common.QueryAndSetPostCache([]models.WpPosts{{Id: ID}}) + if er != nil { + err = er + return + } + post = common.GetPostFromCache(ID) + if post.Id == 0 { + return + } + } + pw := sessions.Default(c).Get("post_password") + showComment := true + common.PasswordProjectTitle(&post) + if post.PostPassword != "" && pw != post.PostPassword { + common.PasswdProjectContent(&post) + showComment = false + } + recent, err := common.RecentPosts() + archive, err := common.Archives() + categoryItems, err := common.Categories() + canComment := false + if post.CommentStatus == "open" { + canComment = true + } + prev, err := models.FirstOne[models.WpPosts](models.SqlBuilder{ + {"post_date", "<", post.PostDate.Format("2006-01-02 15:04:05")}, + {"post_status", "publish"}, + {"post_type", "post"}, + }, "ID,post_title") + if prev.Id > 0 { + if _, ok := common.PostsCache.Load(prev.Id); !ok { + common.QueryAndSetPostCache([]models.WpPosts{prev}) + } + } + next, err := models.FirstOne[models.WpPosts](models.SqlBuilder{ + {"post_date", ">", post.PostDate.Format("2006-01-02 15:04:05")}, + {"post_status", "publish"}, + {"post_type", "post"}, + }, "ID,post_title,post_password") + if prev.Id > 0 { + if _, ok := common.PostsCache.Load(next.Id); !ok { + common.QueryAndSetPostCache([]models.WpPosts{next}) + } + } + h = gin.H{ + "title": fmt.Sprintf("%s-%s", post.PostTitle, models.Options["blogname"]), + "post": post, + "options": models.Options, + "recentPosts": recent, + "archives": archive, + "categories": categoryItems, + "comment": showComment, + "canComment": canComment, + "prev": prev, + "next": next, + } } diff --git a/actions/index.go b/actions/index.go index eae2daa..5e94713 100644 --- a/actions/index.go +++ b/actions/index.go @@ -12,12 +12,9 @@ import ( "regexp" "strconv" "strings" - "sync" ) -var PostsCache sync.Map - -type IndexHandle struct { +type indexHandle struct { c *gin.Context session sessions.Session page int @@ -39,8 +36,8 @@ type IndexHandle struct { paginationStep int } -func NewIndexHandle(ctx *gin.Context) *IndexHandle { - return &IndexHandle{ +func newIndexHandle(ctx *gin.Context) *indexHandle { + return &indexHandle{ c: ctx, session: sessions.Default(ctx), page: 1, @@ -58,17 +55,17 @@ func NewIndexHandle(ctx *gin.Context) *IndexHandle { status: []interface{}{"publish"}, } } -func (h *IndexHandle) setTitleLR(l, r string) { +func (h *indexHandle) setTitleLR(l, r string) { h.titleL = l h.titleR = r } -func (h *IndexHandle) getTitle() string { +func (h *indexHandle) getTitle() string { h.title = fmt.Sprintf("%s-%s", h.titleL, h.titleR) return h.title } -func (h *IndexHandle) parseParams() { +func (h *indexHandle) parseParams() { h.order = h.c.Query("order") if !helper.IsContainInArr(h.order, []string{"asc", "desc"}) { h.order = "asc" @@ -143,73 +140,18 @@ func (h *IndexHandle) parseParams() { } } -func (h *IndexHandle) getTotalPage(totalRaws int) int { +func (h *indexHandle) getTotalPage(totalRaws int) int { h.totalPage = int(math.Ceil(float64(totalRaws) / float64(h.pageSize))) return h.totalPage } -func (h *IndexHandle) queryAndSetPostCache(postIds []models.WpPosts) (err error) { - var all []uint64 - var needQuery []interface{} - for _, wpPosts := range postIds { - all = append(all, wpPosts.Id) - if _, ok := PostsCache.Load(wpPosts.Id); !ok { - needQuery = append(needQuery, wpPosts.Id) - } - } - if len(needQuery) > 0 { - rawPosts, er := models.Find[models.WpPosts](models.SqlBuilder{{ - "Id", "in", "", - }}, "a.*,ifnull(d.name,'') category_name,ifnull(taxonomy,'') `taxonomy`", "", nil, models.SqlBuilder{{ - "a", "left join", "wp_term_relationships b", "a.Id=b.object_id", - }, { - "left join", "wp_term_taxonomy c", "b.term_taxonomy_id=c.term_taxonomy_id", - }, { - "left join", "wp_terms d", "c.term_id=d.term_id", - }}, 0, needQuery) - if er != nil { - err = er - return - } - postsMap := make(map[uint64]*models.WpPosts) - for i, post := range rawPosts { - v, ok := postsMap[post.Id] - if !ok { - v = &rawPosts[i] - } - if post.Taxonomy == "category" { - v.Categories = append(v.Categories, post.CategoryName) - } else if post.Taxonomy == "post_tag" { - v.Tags = append(v.Tags, post.CategoryName) - } - postsMap[post.Id] = v - } - for _, pp := range postsMap { - if len(pp.Categories) > 0 { - t := make([]string, 0, len(pp.Categories)) - for _, cat := range pp.Categories { - t = append(t, fmt.Sprintf(`%s`, cat, cat)) - } - pp.CategoriesHtml = strings.Join(t, "、") - } - if len(pp.Tags) > 0 { - t := make([]string, 0, len(pp.Tags)) - for _, cat := range pp.Tags { - t = append(t, fmt.Sprintf(``, cat, cat)) - } - pp.TagsHtml = strings.Join(t, "、") - } - PostsCache.Store(pp.Id, pp) - } - } - return -} - func Index(c *gin.Context) { - h := NewIndexHandle(c) + h := newIndexHandle(c) h.parseParams() + ginH := gin.H{} postIds, totalRaw, err := models.SimplePagination[models.WpPosts](h.where, "ID", "", h.page, h.pageSize, h.orderBy, h.join, h.postType, h.status) defer func() { + c.HTML(http.StatusOK, "index", ginH) if err != nil { c.Error(err) } @@ -220,27 +162,28 @@ func Index(c *gin.Context) { if len(postIds) < 1 && h.category != "" { h.titleL = "未找到页面" } - err = h.queryAndSetPostCache(postIds) + err = common.QueryAndSetPostCache(postIds) pw := h.session.Get("post_password") for i, v := range postIds { - post, _ := PostsCache.Load(v.Id) + post, _ := common.PostsCache.Load(v.Id) pp := post.(*models.WpPosts) px := *pp + common.PasswordProjectTitle(&px) if px.PostPassword != "" && pw != px.PostPassword { - common.PasswdProject(&px) + common.PasswdProjectContent(&px) } postIds[i] = px } recent, err := common.RecentPosts() for i, post := range recent { if post.PostPassword != "" && pw != post.PostPassword { - common.PasswdProject(&recent[i]) + common.PasswdProjectContent(&recent[i]) } } archive, err := common.Archives() categoryItems, err := common.Categories() q := c.Request.URL.Query().Encode() - c.HTML(http.StatusOK, "index.html", gin.H{ + ginH = gin.H{ "posts": postIds, "options": models.Options, "recentPosts": recent, @@ -251,7 +194,7 @@ func Index(c *gin.Context) { "search": h.search, "header": h.header, "title": h.getTitle(), - }) + } } func pagination(currentPage, totalPage, step int, path, query string) (html string) { diff --git a/go.mod b/go.mod index 3758efe..a53835b 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github/fthvgb1/wp-go go 1.18 require ( + github.com/gin-contrib/sessions v0.0.5 github.com/gin-gonic/gin v1.8.1 github.com/go-sql-driver/mysql v1.6.0 github.com/jmoiron/sqlx v1.3.5 @@ -10,7 +11,6 @@ require ( ) require ( - github.com/gin-contrib/sessions v0.0.5 // indirect github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-playground/locales v0.14.0 // indirect github.com/go-playground/universal-translator v0.18.0 // indirect diff --git a/route/route.go b/route/route.go index f2634f5..40318ff 100644 --- a/route/route.go +++ b/route/route.go @@ -22,10 +22,13 @@ func SetupRouter() *gin.Engine { return template.HTML(s) }, "dateCh": func(t time.Time) interface{} { - return t.Format("2006年01月02日") + return t.Format("2006年 01月 02日") }, }) - loadTemplates(r, "**/*") + reader := templates.NewFsTemplate(r.FuncMap) + reader.AddTemplate("index", "posts/index.html", "layout/*.html") + reader.AddTemplate("detail", "posts/detail.html", "layout/*.html") + r.HTMLRender = reader r.Use(middleware.SetStaticFileCache) //gzip 因为一般会用nginx做反代时自动使用gzip,所以go这边本身可以不用 /*r.Use(gzip.Gzip(gzip.DefaultCompression, gzip.WithExcludedPaths([]string{ @@ -53,9 +56,3 @@ func SetupRouter() *gin.Engine { return r } - -func loadTemplates(engine *gin.Engine, pattern string) { - templ := template.New("").Funcs(engine.FuncMap).Delims("{{", "}}") - templ = template.Must(templ.ParseFS(templates.TemplateFs, pattern)) - engine.SetHTMLTemplate(templ) -} diff --git a/templates/posts/detail.html b/templates/posts/detail.html new file mode 100644 index 0000000..d72daf3 --- /dev/null +++ b/templates/posts/detail.html @@ -0,0 +1,133 @@ +{{template "layout/base" .}} +{{define "content"}} +
+
+ + +
+ +
+

{{.post.PostTitle}}

+ +
+ {{.post.PostContent|unescaped}} +
+ + +
+ + 发布于 + + + + + {{if .post.CategoriesHtml}} + + 分类 + {{.post.CategoriesHtml|unescaped}} + + {{end}} + + {{if .post.TagsHtml}} + + 标签 + {{.post.TagsHtml|unescaped}} + + {{end}} +
+ + +
+ +
+ +

+ 《{{.post.PostTitle}}》上有1条评论

+ + +
    +
  1. + +
  2. +
+ + {{if .canComment}} +
+

发表回复 + + + +

+ +

您的电子邮箱地址不会被公开。 +

+

+

+

+

+ +

+

+ +

+ + +

+ +
+ {{end}} +
+ + +
+
+{{end}} diff --git a/templates/posts/index.html b/templates/posts/index.html index ed11355..a4f7af0 100644 --- a/templates/posts/index.html +++ b/templates/posts/index.html @@ -16,7 +16,7 @@ {{end}} {{ range $k,$v:=.posts}}
+ class="post-{{$v.Id}} post type-post status-publish format-standard hentry category">

@@ -25,7 +25,7 @@

-

{{$v.PostContent|unescaped}}

+ {{$v.PostContent|unescaped}}