diff --git a/internal/actions/detail.go b/internal/actions/detail.go index 7d1a863..7b898ec 100644 --- a/internal/actions/detail.go +++ b/internal/actions/detail.go @@ -4,16 +4,13 @@ import ( "fmt" "github.com/fthvgb1/wp-go/internal/pkg/cache" "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" "github.com/fthvgb1/wp-go/internal/wpconfig" "github.com/gin-contrib/sessions" "github.com/gin-gonic/gin" "net/http" - "sort" "strconv" - "strings" ) type detailHandler struct { @@ -22,9 +19,6 @@ type detailHandler struct { func Detail(c *gin.Context) { var err error - hh := detailHandler{ - c, - } recent := cache.RecentPosts(c, 5) archive := cache.Archives(c) categoryItems := cache.Categories(c) @@ -92,7 +86,7 @@ func Detail(c *gin.Context) { plugins.ApplyPlugin(plugins.NewPostPlugin(c, plugins.Detail), &post) comments, err := cache.PostComments(c, post.Id) logs.ErrPrintln(err, "get post comment", post.Id) - commentss := treeComments(comments) + ginH["comments"] = comments prev, next, err := cache.GetContextPost(c, post.Id, post.PostDate) logs.ErrPrintln(err, "get pre and next post", post.Id, post.PostDate) ginH["title"] = fmt.Sprintf("%s-%s", post.PostTitle, wpconfig.Options.Value("blogname")) @@ -105,158 +99,8 @@ func Detail(c *gin.Context) { logs.ErrPrintln(err, "get comment depth ", depth) d = 5 } - ginH["comments"] = hh.formatComment(commentss, 1, d) + ginH["maxDep"] = d ginH["next"] = next ginH["user"] = user ginH["scene"] = plugins.Detail } - -type Comment struct { - models.Comments - Children []*Comment -} - -type Comments []*Comment - -func (c Comments) Len() int { - return len(c) -} - -func (c Comments) Less(i, j int) bool { - return c[i].CommentId < c[j].CommentId -} - -func (c Comments) Swap(i, j int) { - c[i], c[j] = c[j], c[i] -} - -func (d detailHandler) formatComment(comments Comments, depth, maxDepth int) (html string) { - s := strings.Builder{} - if depth > maxDepth { - comments = findComments(comments) - } - sort.Sort(comments) - for i, comment := range comments { - eo := "even" - if (i+1)%2 == 0 { - eo = "odd" - } - p := "" - fl := false - if len(comment.Children) > 0 && depth < maxDepth+1 { - p = "parent" - fl = true - } - s.WriteString(d.formatLi(comment.Comments, depth, eo, p)) - if fl { - depth++ - s.WriteString(`
    `) - s.WriteString(d.formatComment(comment.Children, depth, maxDepth)) - s.WriteString(`
`) - } - s.WriteString("") - i++ - if i >= len(comments) { - break - } - } - - html = s.String() - return -} - -func findComments(comments Comments) Comments { - var r Comments - for _, comment := range comments { - tmp := *comment - tmp.Children = nil - r = append(r, &tmp) - if len(comment.Children) > 0 { - t := findComments(comment.Children) - r = append(r, t...) - } - } - return r -} - -func treeComments(comments []models.Comments) Comments { - var r = map[uint64]*Comment{ - 0: { - Comments: models.Comments{}, - }, - } - var top []*Comment - for _, comment := range comments { - c := Comment{ - Comments: comment, - Children: []*Comment{}, - } - r[comment.CommentId] = &c - if comment.CommentParent == 0 { - top = append(top, &c) - } - } - for id, son := range r { - if id == son.CommentParent { - continue - } - parent := r[son.CommentParent] - parent.Children = append(parent.Children, son) - } - return top -} - -func (d detailHandler) formatLi(comments models.Comments, depth int, eo, parent string) string { - li := ` -
  • -
    - - -
    -

    {{CommentContent}}

    -
    - -
    - 回复 -
    -
    - -` - for k, v := range map[string]string{ - "{{CommentId}}": strconv.FormatUint(comments.CommentId, 10), - "{{Depth}}": strconv.Itoa(depth), - "{{Gravatar}}": plugins.Gravatar(comments.CommentAuthorEmail, d.Context.Request.TLS != nil), - "{{CommentAuthorUrl}}": comments.CommentAuthorUrl, - "{{CommentAuthor}}": comments.CommentAuthor, - "{{PostId}}": strconv.FormatUint(comments.CommentPostId, 10), - "{{CommentDateGmt}}": comments.CommentDateGmt.String(), - "{{CommentDate}}": comments.CommentDate.Format("2006-01-02 15:04"), - "{{CommentContent}}": comments.CommentContent, - "{{eo}}": eo, - "{{parent}}": parent, - } { - li = strings.Replace(li, k, v, -1) - } - return li -} diff --git a/internal/plugins/comment.go b/internal/plugins/comment.go index d5c343e..edf61ca 100644 --- a/internal/plugins/comment.go +++ b/internal/plugins/comment.go @@ -1 +1,191 @@ package plugins + +import ( + "github.com/fthvgb1/wp-go/helper/slice" + "github.com/fthvgb1/wp-go/internal/pkg/models" + "github.com/gin-gonic/gin" + "strconv" + "strings" +) + +type CommentHandler struct { + *gin.Context + comments []*Comments + maxDepth int + depth int + i CommentHtml +} + +type Comments struct { + models.Comments + Children []*Comments +} + +type CommentHtml interface { + Sort(i, j *Comments) bool + FormatLi(c *gin.Context, m models.Comments, depth int, eo, parent string) string +} + +func FormatComments(c *gin.Context, i CommentHtml, comments []models.Comments, maxDepth int) string { + tree := treeComments(comments) + h := CommentHandler{ + Context: c, + comments: tree, + maxDepth: maxDepth, + depth: 1, + i: i, + } + return h.formatComment(h.comments, true) +} + +func (d CommentHandler) formatComment(comments []*Comments, isTop bool) (html string) { + s := strings.Builder{} + if d.depth > d.maxDepth { + comments = d.findComments(comments) + } + slice.SortSelf(comments, d.i.Sort) + for i, comment := range comments { + eo := "even" + if (i+1)%2 == 0 { + eo = "odd" + } + parent := "" + fl := false + if len(comment.Children) > 0 && d.depth < d.maxDepth+1 { + parent = "parent" + fl = true + } + s.WriteString(d.i.FormatLi(d.Context, comment.Comments, d.depth, eo, parent)) + if fl { + d.depth++ + s.WriteString(`
      `) + s.WriteString(d.formatComment(comment.Children, false)) + s.WriteString(`
    `) + if isTop { + d.depth = 1 + } + } + s.WriteString("
  • ") + } + + html = s.String() + return +} + +func (d CommentHandler) findComments(comments []*Comments) []*Comments { + var r []*Comments + for _, comment := range comments { + tmp := *comment + comment.Children = nil + r = append(r, &tmp) + if len(comment.Children) > 0 { + t := d.findComments(comment.Children) + r = append(r, t...) + } + } + return r +} + +func treeComments(comments []models.Comments) []*Comments { + var r = map[uint64]*Comments{ + 0: { + Comments: models.Comments{}, + }, + } + var top []*Comments + for _, comment := range comments { + c := Comments{ + Comments: comment, + Children: []*Comments{}, + } + r[comment.CommentId] = &c + if comment.CommentParent == 0 { + top = append(top, &c) + } + } + for id, son := range r { + if id == son.CommentParent { + continue + } + parent := r[son.CommentParent] + parent.Children = append(parent.Children, son) + } + return top +} + +func CommonLi() string { + return li +} + +var commonCommentFormat = CommonCommentFormat{} + +func CommentRender() CommonCommentFormat { + return commonCommentFormat +} + +type CommonCommentFormat struct { +} + +func (c CommonCommentFormat) Sort(i, j *Comments) bool { + return i.CommentDate.UnixNano() < j.CommentDate.UnixNano() +} + +func (c CommonCommentFormat) FormatLi(ctx *gin.Context, m models.Comments, depth int, eo, parent string) string { + return FormatLi(CommonLi(), ctx, m, depth, eo, parent) +} + +var li = ` +
  • +
    + + +
    +

    {{CommentContent}}

    +
    + +
    + 回复 +
    +
    + +` + +func FormatLi(li string, c *gin.Context, comments models.Comments, depth int, eo, parent string) string { + for k, v := range map[string]string{ + "{{CommentId}}": strconv.FormatUint(comments.CommentId, 10), + "{{Depth}}": strconv.Itoa(depth), + "{{Gravatar}}": Gravatar(comments.CommentAuthorEmail, c.Request.TLS != nil), + "{{CommentAuthorUrl}}": comments.CommentAuthorUrl, + "{{CommentAuthor}}": comments.CommentAuthor, + "{{PostId}}": strconv.FormatUint(comments.CommentPostId, 10), + "{{CommentDateGmt}}": comments.CommentDateGmt.String(), + "{{CommentDate}}": comments.CommentDate.Format("2006-01-02 15:04"), + "{{CommentContent}}": comments.CommentContent, + "{{eo}}": eo, + "{{parent}}": parent, + } { + li = strings.Replace(li, k, v, -1) + } + return li +} diff --git a/internal/theme/fs.go b/internal/theme/fs.go index b4e5e67..b84499a 100644 --- a/internal/theme/fs.go +++ b/internal/theme/fs.go @@ -26,7 +26,7 @@ func GetTemplate() *multipTemplate.MultipleFsTemplate { // 所有主题模板通用设置 func commonTemplate(t *multipTemplate.MultipleFsTemplate) { - m, err := fs.Glob(t.Fs, "*/*[^layout]/*.gohtml") + m, err := fs.Glob(t.Fs, "*/posts/*.gohtml") if err != nil { panic(err) } diff --git a/internal/theme/hook.go b/internal/theme/hook.go index ad31852..23ce9c8 100644 --- a/internal/theme/hook.go +++ b/internal/theme/hook.go @@ -3,6 +3,7 @@ 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" @@ -34,6 +35,7 @@ func Hook(themeName string, code int, c *gin.Context, h gin.H, scene, status int c.HTML(code, "twentyfifteen/posts/index.gohtml", h) return } else if scene == plugins.Detail { + h["comments"] = plugins.FormatComments(c, plugins.CommentRender(), h["comments"].([]models.Comments), h["maxDep"].(int)) c.HTML(code, "twentyfifteen/posts/detail.gohtml", h) return } diff --git a/internal/theme/twentyseventeen/layout/comment.gohtml b/internal/theme/twentyseventeen/layout/comment.gohtml new file mode 100644 index 0000000..b33383f --- /dev/null +++ b/internal/theme/twentyseventeen/layout/comment.gohtml @@ -0,0 +1,38 @@ +{{define "respond"}} +
    +

    发表回复 + + + +

    +
    +

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

    +

    + +

    +

    + +

    + +

    + + +

    + +

    + + + +

    +
    +
    +{{end}} \ No newline at end of file diff --git a/internal/theme/twentyseventeen/posts/detail.gohtml b/internal/theme/twentyseventeen/posts/detail.gohtml index d59e113..7eb8a97 100644 --- a/internal/theme/twentyseventeen/posts/detail.gohtml +++ b/internal/theme/twentyseventeen/posts/detail.gohtml @@ -65,50 +65,15 @@ {{ if .showComment}}
    {{ if gt .post.CommentCount 0}} -

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

    +

    “{{.post.PostTitle}}”的{{.post.CommentCount}}个回复

      {{.comments|unescaped}}
    {{end}} {{if eq .post.CommentStatus "open"}} -
    -

    发表回复 - - - -

    -
    -

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

    -

    - -

    -

    - -

    - -

    -

    - -

    - - - -

    -
    -
    + {{template "respond" .}} + {{else}}

    评论已关闭。

    {{end}} @@ -118,22 +83,32 @@