optimize pagination interface and add twentyseventeen comments pagination nav

This commit is contained in:
xing 2023-12-23 20:17:42 +08:00
parent 088fc306de
commit f7d2377101
8 changed files with 160 additions and 66 deletions

View File

@ -143,14 +143,24 @@ type CommonCommentFormat struct {
} }
func (c CommonCommentFormat) FormatLi(_ context.Context, m models.Comments, currentDepth, maxDepth, page int, isTls, isThreadComments bool, eo, parent string) string { func (c CommonCommentFormat) FormatLi(_ context.Context, m models.Comments, currentDepth, maxDepth, page int, isTls, isThreadComments bool, eo, parent string) string {
return FormatLi(CommonLi(), m, currentDepth, maxDepth, page, isTls, isThreadComments, eo, parent) return FormatLi(li, m, respondsFn, currentDepth, maxDepth, page, isTls, isThreadComments, eo, parent)
} }
func (c CommonCommentFormat) FloorOrder(wpOrder string, i, j models.PostComments) bool { func (c CommonCommentFormat) FloorOrder(wpOrder string, i, j models.PostComments) bool {
return i.CommentId > j.CommentId return i.CommentId > j.CommentId
} }
func respond(m models.Comments, isShow bool) string {
if !isShow { type RespondFn func(m models.Comments, depth, maxDepth int, isThreadComments bool) string
var respondsFn = Responds(respondTml)
func RespondsFn() RespondFn {
return respondsFn
}
func Responds(respondTml string) RespondFn {
return func(m models.Comments, depth, maxDepth int, isThreadComments bool) string {
if !isThreadComments || depth >= maxDepth {
return "" return ""
} }
pId := number.IntToString(m.CommentPostId) pId := number.IntToString(m.CommentPostId)
@ -160,6 +170,7 @@ func respond(m models.Comments, isShow bool) string {
"{{CommentId}}": cId, "{{CommentId}}": cId,
"{{CommentAuthor}}": m.CommentAuthor, "{{CommentAuthor}}": m.CommentAuthor,
}) })
}
} }
var li = ` var li = `
@ -198,11 +209,7 @@ var respondTml = `<div class="reply">
aria-label="回复给{{CommentAuthor}}">回复</a> aria-label="回复给{{CommentAuthor}}">回复</a>
</div>` </div>`
func FormatLi(li string, comments models.Comments, currentDepth, maxDepth, page int, isTls, isThreadComments bool, eo, parent string) string { func FormatLi(li string, comments models.Comments, respond RespondFn, currentDepth, maxDepth, page int, isTls, isThreadComments bool, eo, parent string) string {
isShow := false
if isThreadComments && currentDepth < maxDepth {
isShow = true
}
for k, v := range map[string]string{ for k, v := range map[string]string{
"{{CommentId}}": strconv.FormatUint(comments.CommentId, 10), "{{CommentId}}": strconv.FormatUint(comments.CommentId, 10),
"{{Depth}}": strconv.Itoa(currentDepth), "{{Depth}}": strconv.Itoa(currentDepth),
@ -216,7 +223,7 @@ func FormatLi(li string, comments models.Comments, currentDepth, maxDepth, page
"{{CommentContent}}": comments.CommentContent, "{{CommentContent}}": comments.CommentContent,
"{{eo}}": eo, "{{eo}}": eo,
"{{parent}}": parent, "{{parent}}": parent,
"{{respond}}": respond(comments, isShow), "{{respond}}": respond(comments, currentDepth, maxDepth, isThreadComments),
} { } {
li = strings.Replace(li, k, v, -1) li = strings.Replace(li, k, v, -1)
} }

View File

@ -5,6 +5,7 @@ import (
"github.com/fthvgb1/wp-go/app/wpconfig" "github.com/fthvgb1/wp-go/app/wpconfig"
"github.com/fthvgb1/wp-go/helper" "github.com/fthvgb1/wp-go/helper"
str "github.com/fthvgb1/wp-go/helper/strings" str "github.com/fthvgb1/wp-go/helper/strings"
"net/url"
"regexp" "regexp"
"strings" "strings"
) )
@ -60,6 +61,10 @@ func (p PageEle) Dots() string {
return p.DotsEle return p.DotsEle
} }
func (p PageEle) Step() int {
return 0
}
func (p PageEle) Middle(page int, url string) string { func (p PageEle) Middle(page int, url string) string {
return fmt.Sprintf(p.MiddleEle, url, page) return fmt.Sprintf(p.MiddleEle, url, page)
} }
@ -67,7 +72,8 @@ func (p PageEle) Middle(page int, url string) string {
var reg = regexp.MustCompile(`(/page)/(\d+)`) var reg = regexp.MustCompile(`(/page)/(\d+)`)
var commentReg = regexp.MustCompile(`/comment-page-(\d+)`) var commentReg = regexp.MustCompile(`/comment-page-(\d+)`)
func (p PageEle) Url(path, query string, page int) string { func (p PageEle) Urls(u url.URL, page int, isTLS bool) string {
var path, query = u.Path, u.RawQuery
if !strings.Contains(path, "/page/") { if !strings.Contains(path, "/page/") {
path = fmt.Sprintf("%s%s", path, "/page/1") path = fmt.Sprintf("%s%s", path, "/page/1")
} }
@ -84,11 +90,12 @@ func (p PageEle) Url(path, query string, page int) string {
return str.Join(path, query) return str.Join(path, query)
} }
func (p CommentPageEle) Url(path, query string, page int) string { func (p CommentPageEle) Urls(u url.URL, page int, isTLS bool) string {
var path, query = u.Path, u.RawQuery
if !strings.Contains(path, "/comment-page-") { if !strings.Contains(path, "/comment-page-") {
path = fmt.Sprintf("%s%s", path, "/comment-page-1") path = fmt.Sprintf("%s%s", path, "/comment-page-1#comments")
} }
path = commentReg.ReplaceAllString(path, fmt.Sprintf("/comment-page-%d", page)) path = commentReg.ReplaceAllString(path, fmt.Sprintf("/comment-page-%d#comments", page))
path = strings.Replace(path, "//", "/", -1) path = strings.Replace(path, "//", "/", -1)
if path == "" { if path == "" {
path = "/" path = "/"
@ -109,6 +116,48 @@ func (p CommentPageEle) Prev(url string) string {
return fmt.Sprintf(p.PrevEle, url, helper.Or(wpconfig.GetOption("comment_order") == "asc", "较早评论", "较新评论")) return fmt.Sprintf(p.PrevEle, url, helper.Or(wpconfig.GetOption("comment_order") == "asc", "较早评论", "较新评论"))
} }
func (p CommentPageEle) Step() int {
return 0
}
func (p CommentPageEle) Next(url string) string { func (p CommentPageEle) Next(url string) string {
return fmt.Sprintf(p.NextEle, url, helper.Or(wpconfig.GetOption("comment_order") == "asc", "较新评论", "较早评论")) return fmt.Sprintf(p.NextEle, url, helper.Or(wpconfig.GetOption("comment_order") == "asc", "较新评论", "较早评论"))
} }
type PaginationNav struct {
Currents func(page, totalPage, totalRows int) string
Prevs func(url string) string
Nexts func(url string) string
Dotss func() string
Middles func(page int, url string) string
Urlss func(u url.URL, page int, isTLS bool) string
Steps func() int
}
func (p PaginationNav) Current(page, totalPage, totalRows int) string {
return p.Currents(page, totalPage, totalRows)
}
func (p PaginationNav) Prev(url string) string {
return p.Prevs(url)
}
func (p PaginationNav) Next(url string) string {
return p.Nexts(url)
}
func (p PaginationNav) Dots() string {
return p.Dotss()
}
func (p PaginationNav) Middle(page int, url string) string {
return p.Middles(page, url)
}
func (p PaginationNav) Urls(u url.URL, page int, isTLS bool) string {
return p.Urlss(u, page, isTLS)
}
func (p PaginationNav) Step() int {
return p.Steps()
}

View File

@ -64,12 +64,21 @@
{{ if .showComment}} {{ if .showComment}}
<div id="comments" class="comments-area"> <div id="comments" class="comments-area">
{{ if gt .post.CommentCount 0}} {{ if ne .comments ""}}
<h2 class="comments-title">“{{.post.PostTitle}}”的{{.post.CommentCount}}个回复 </h2> <h2 class="comments-title">“{{.post.PostTitle}}”的{{.totalCommentNum}}个回复 </h2>
<ol class="comment-list"> <ol class="comment-list">
{{.comments|unescaped}} {{.comments|unescaped}}
</ol> </ol>
{{if gt .totalCommentPage 1}}
<nav class="navigation comments-pagination" aria-label="评论">
<h2 class="screen-reader-text">评论导航</h2>
<div class="nav-links">
{{ .commentPageNav|unescaped}}
</div><!-- .nav-links -->
</nav>
{{end}}
{{end}} {{end}}
{{if eq .post.CommentStatus "open"}} {{if eq .post.CommentStatus "open"}}
{{template "respond" .}} {{template "respond" .}}

View File

@ -15,6 +15,7 @@ import (
"github.com/fthvgb1/wp-go/cache/reload" "github.com/fthvgb1/wp-go/cache/reload"
"github.com/fthvgb1/wp-go/helper" "github.com/fthvgb1/wp-go/helper"
str "github.com/fthvgb1/wp-go/helper/strings" str "github.com/fthvgb1/wp-go/helper/strings"
"github.com/fthvgb1/wp-go/plugin/pagination"
"strings" "strings"
) )
@ -27,9 +28,23 @@ var paginate = func() plugins.PageEle {
p.NextEle = strings.Replace(p.NextEle, "下一页", `<span class="screen-reader-text">下一页</span> p.NextEle = strings.Replace(p.NextEle, "下一页", `<span class="screen-reader-text">下一页</span>
<svg class="icon icon-arrow-right" aria-hidden="true" role="img"> <use href="#icon-arrow-right" xlink:href="#icon-arrow-right"></use> <svg class="icon icon-arrow-right" aria-hidden="true" role="img"> <use href="#icon-arrow-right" xlink:href="#icon-arrow-right"></use>
</svg>`, 1) </svg>`, 1)
commentPageEle = plugins.PaginationNav{
Currents: p.Current,
Prevs: p.Prev,
Nexts: p.Next,
Dotss: p.Dots,
Middles: p.Middle,
Steps: func() int {
return 2
},
Urlss: plugins.TwentyFifteenCommentPagination().Urls,
}
return p return p
}() }()
var commentPageEle pagination.Render
func Hook(h *wp.Handle) { func Hook(h *wp.Handle) {
wp.Run(h, configs) wp.Run(h, configs)
} }
@ -56,6 +71,7 @@ func configs(h *wp.Handle) {
) )
videoHeader(h) videoHeader(h)
h.Detail.CommentRender = commentFormat h.Detail.CommentRender = commentFormat
h.Detail.CommentPageEle = commentPageEle
h.CommonComponents() h.CommonComponents()
h.Index.SetPageEle(paginate) h.Index.SetPageEle(paginate)
wp.ReplyCommentJs(h) wp.ReplyCommentJs(h)
@ -103,20 +119,20 @@ type comment struct {
plugins.CommonCommentFormat plugins.CommonCommentFormat
} }
var commentLi = plugins.CommonLi()
var respondFn = plugins.Responds(respondStr)
func (c comment) FormatLi(_ context.Context, m models.Comments, depth, maxDepth, page int, isTls, isThreadComments bool, eo, parent string) string { func (c comment) FormatLi(_ context.Context, m models.Comments, depth, maxDepth, page int, isTls, isThreadComments bool, eo, parent string) string {
templ := plugins.CommonLi() return plugins.FormatLi(commentLi, m, respondFn, depth, maxDepth, page, isTls, isThreadComments, eo, parent)
templ = strings.ReplaceAll(templ, `<a rel="nofollow" class="comment-reply-link"
href="/p/{{PostId}}?replytocom={{CommentId}}#respond" data-commentid="{{CommentId}}" data-postid="{{PostId}}"
data-belowelement="div-comment-{{CommentId}}" data-respondelement="respond"
data-replyto="回复给{{CommentAuthor}}"
aria-label="回复给{{CommentAuthor}}">回复</a>`, `<a rel="nofollow" class="comment-reply-link"
href="/p/{{PostId}}?replytocom={{CommentId}}#respond" data-commentid="{{CommentId}}" data-postid="{{PostId}}"
data-belowelement="div-comment-{{CommentId}}" data-respondelement="respond"
data-replyto="回复给{{CommentAuthor}}"
aria-label="回复给{{CommentAuthor}}"><svg class="icon icon-mail-reply" aria-hidden="true" role="img"> <use href="#icon-mail-reply" xlink:href="#icon-mail-reply"></use> </svg>回复</a>`)
return plugins.FormatLi(templ, m, depth, maxDepth, page, isTls, isThreadComments, eo, parent)
} }
var respondStr = `<a rel="nofollow" class="comment-reply-link"
href="/p/{{PostId}}?replytocom={{CommentId}}#respond" data-commentid="{{CommentId}}" data-postid="{{PostId}}"
data-belowelement="div-comment-{{CommentId}}" data-respondelement="respond"
data-replyto="回复给{{CommentAuthor}}"
aria-label="回复给{{CommentAuthor}}"><svg class="icon icon-mail-reply" aria-hidden="true" role="img"> <use href="#icon-mail-reply" xlink:href="#icon-mail-reply"></use> </svg>回复</a>`
func postThumbnail(h *wp.Handle, posts *models.Posts) { func postThumbnail(h *wp.Handle, posts *models.Posts) {
if posts.Thumbnail.Path != "" { if posts.Thumbnail.Path != "" {
posts.Thumbnail.Sizes = "(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px" posts.Thumbnail.Sizes = "(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px"

View File

@ -25,6 +25,7 @@ type DetailHandle struct {
Page int Page int
Limit int Limit int
Post models.Posts Post models.Posts
CommentPageEle pagination.Render
TotalRaw int TotalRaw int
} }
@ -132,8 +133,10 @@ func (d *DetailHandle) RenderComment() {
d.SetErr(err) d.SetErr(err)
return return
} }
paginations := pagination.NewParsePagination(d.TotalRaw, d.Limit, d.Page, 1, d.C.Request.URL.RawQuery, d.C.Request.URL.Path) if d.CommentPageEle == nil {
d.ginH["commentPageNav"] = pagination.Paginate(plugins.TwentyFifteenCommentPagination(), paginations) d.CommentPageEle = plugins.TwentyFifteenCommentPagination()
}
d.ginH["commentPageNav"] = pagination.Paginate(d.CommentPageEle, d.TotalRaw, d.Limit, d.Page, 1, *d.C.Request.URL, d.IsHttps())
} }

View File

@ -20,7 +20,7 @@ type IndexHandle struct {
*Handle *Handle
Param *IndexParams Param *IndexParams
Posts []models.Posts Posts []models.Posts
pageEle pagination.Elements pageEle pagination.Render
TotalRows int TotalRows int
postsPlugin PostsPlugin postsPlugin PostsPlugin
} }
@ -33,11 +33,11 @@ func (i *IndexHandle) SetListPlugin(listPlugin func(*Handle, *models.Posts)) {
i.postsPlugin = listPlugin i.postsPlugin = listPlugin
} }
func (i *IndexHandle) PageEle() pagination.Elements { func (i *IndexHandle) PageEle() pagination.Render {
return i.pageEle return i.pageEle
} }
func (i *IndexHandle) SetPageEle(pageEle pagination.Elements) { func (i *IndexHandle) SetPageEle(pageEle pagination.Render) {
i.pageEle = pageEle i.pageEle = pageEle
} }
@ -116,8 +116,7 @@ func (i *IndexHandle) Pagination() {
if q != "" { if q != "" {
q = fmt.Sprintf("?%s", q) q = fmt.Sprintf("?%s", q)
} }
paginations := pagination.NewParsePagination(i.TotalRows, i.Param.PageSize, i.Param.Page, i.Param.PaginationStep, q, i.C.Request.URL.Path) i.ginH["pagination"] = pagination.Paginate(i.pageEle, i.TotalRows, i.Param.PageSize, i.Param.Page, i.Param.PaginationStep, *i.C.Request.URL, i.IsHttps())
i.ginH["pagination"] = pagination.Paginate(i.pageEle, paginations)
} }

View File

@ -130,6 +130,7 @@ func InitHandle(fn func(*Handle), h *Handle) {
h.Index.postsPlugin = hh.Index.postsPlugin h.Index.postsPlugin = hh.Index.postsPlugin
h.Index.pageEle = hh.Index.pageEle h.Index.pageEle = hh.Index.pageEle
h.Detail.CommentRender = hh.Detail.CommentRender h.Detail.CommentRender = hh.Detail.CommentRender
h.Detail.CommentPageEle = hh.Detail.CommentPageEle
h.handlers = hh.handlers h.handlers = hh.handlers
h.handleHook = hh.handleHook h.handleHook = hh.handleHook
h.componentHook = hh.componentHook h.componentHook = hh.componentHook

View File

@ -2,39 +2,49 @@ package pagination
import ( import (
"github.com/fthvgb1/wp-go/helper/number" "github.com/fthvgb1/wp-go/helper/number"
"net/url"
"strings" "strings"
) )
type Elements interface { type Render interface {
Current(page, totalPage, totalRows int) string Current(page, totalPage, totalRows int) string
Prev(url string) string Prev(url string) string
Next(url string) string Next(url string) string
Dots() string Dots() string
Middle(page int, url string) string Middle(page int, url string) string
Url(path, query string, page int) string Urls(u url.URL, page int, isTLS bool) string
Step() int
} }
type ParsePagination struct { type parser struct {
Elements Render
TotalPage int TotalPage int
TotalRaw int TotalRaw int
PageSize int PageSize int
CurrentPage int CurrentPage int
Query string Url url.URL
Path string
Step int Step int
IsTLS bool
} }
func NewParsePagination(totalRaw int, pageSize int, currentPage, step int, query string, path string) ParsePagination { func Paginate(e Render, totalRaw int, pageSize int, currentPage, step int, u url.URL, isTLS bool) string {
return ParsePagination{TotalPage: number.DivideCeil(totalRaw, pageSize), TotalRaw: totalRaw, PageSize: pageSize, CurrentPage: currentPage, Query: query, Path: path, Step: step} st := e.Step()
if st > 0 {
step = st
}
return parser{
Render: e,
TotalPage: number.DivideCeil(totalRaw, pageSize),
TotalRaw: totalRaw,
PageSize: pageSize,
CurrentPage: currentPage,
Url: u,
Step: step,
IsTLS: isTLS,
}.ToHtml()
} }
func Paginate(e Elements, p ParsePagination) string { func (p parser) ToHtml() (html string) {
p.Elements = e
return p.ToHtml()
}
func (p ParsePagination) ToHtml() (html string) {
if p.TotalPage < 2 { if p.TotalPage < 2 {
return return
} }
@ -48,14 +58,14 @@ func (p ParsePagination) ToHtml() (html string) {
start = 1 start = 1
} }
if p.CurrentPage > 1 { if p.CurrentPage > 1 {
s.WriteString(p.Prev(p.Url(p.Path, p.Query, p.CurrentPage-1))) s.WriteString(p.Prev(p.Urls(p.Url, p.CurrentPage-1, p.IsTLS)))
} }
if p.CurrentPage >= p.Step+2 { if p.CurrentPage >= p.Step+2 {
d := false d := false
if p.CurrentPage > p.Step+2 { if p.CurrentPage > p.Step+2 {
d = true d = true
} }
s.WriteString(p.Middle(1, p.Url(p.Path, p.Query, 1))) s.WriteString(p.Middle(1, p.Urls(p.Url, 1, p.IsTLS)))
if d { if d {
s.WriteString(p.Dots()) s.WriteString(p.Dots())
} }
@ -69,7 +79,7 @@ func (p ParsePagination) ToHtml() (html string) {
if p.CurrentPage == page { if p.CurrentPage == page {
h = p.Current(page, p.TotalPage, p.TotalRaw) h = p.Current(page, p.TotalPage, p.TotalRaw)
} else { } else {
h = p.Middle(page, p.Url(p.Path, p.Query, page)) h = p.Middle(page, p.Urls(p.Url, page, p.IsTLS))
} }
s.WriteString(h) s.WriteString(h)
@ -82,10 +92,10 @@ func (p ParsePagination) ToHtml() (html string) {
if d { if d {
s.WriteString(p.Dots()) s.WriteString(p.Dots())
} }
s.WriteString(p.Middle(p.TotalPage, p.Url(p.Path, p.Query, p.TotalPage))) s.WriteString(p.Middle(p.TotalPage, p.Urls(p.Url, p.TotalPage, p.IsTLS)))
} }
if p.CurrentPage < p.TotalPage { if p.CurrentPage < p.TotalPage {
s.WriteString(p.Next(p.Url(p.Path, p.Query, p.CurrentPage+1))) s.WriteString(p.Next(p.Urls(p.Url, p.CurrentPage+1, p.IsTLS)))
} }
html = s.String() html = s.String()
return return