分页器调整及主题hook机制

This commit is contained in:
xing 2023-01-18 23:04:12 +08:00
parent 86adc60c51
commit b8cf654130
7 changed files with 242 additions and 166 deletions

View File

@ -2,20 +2,19 @@ package actions
import ( import (
"fmt" "fmt"
"github.com/fthvgb1/wp-go/helper"
cache2 "github.com/fthvgb1/wp-go/internal/pkg/cache"
dao "github.com/fthvgb1/wp-go/internal/pkg/dao"
"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/fthvgb1/wp-go/model"
"github.com/fthvgb1/wp-go/plugin/pagination"
"github.com/gin-contrib/sessions" "github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github/fthvgb1/wp-go/helper"
"github/fthvgb1/wp-go/internal/actions/theme"
cache2 "github/fthvgb1/wp-go/internal/pkg/cache"
dao "github/fthvgb1/wp-go/internal/pkg/dao"
"github/fthvgb1/wp-go/internal/pkg/models"
"github/fthvgb1/wp-go/internal/plugins"
"github/fthvgb1/wp-go/internal/templates"
"github/fthvgb1/wp-go/internal/wpconfig"
"github/fthvgb1/wp-go/model"
"math" "math"
"net/http" "net/http"
"regexp"
"strconv" "strconv"
"strings" "strings"
"sync/atomic" "sync/atomic"
@ -204,8 +203,7 @@ func Index(c *gin.Context) {
return return
} }
t := getTemplateName() t := getTemplateName()
tmlp := theme.Hook(t, c, ginH, int(h.scene)) theme.Hook(t, stat, c, ginH, int(h.scene))
c.HTML(stat, tmlp, ginH)
}() }()
err = h.parseParams() err = h.parseParams()
if err != nil { if err != nil {
@ -251,13 +249,11 @@ func Index(c *gin.Context) {
} }
ginH["posts"] = postIds ginH["posts"] = postIds
ginH["totalPage"] = h.getTotalPage(totalRaw) ginH["totalPage"] = h.getTotalPage(totalRaw)
ginH["currentPage"] = h.getTotalPage(h.page) ginH["currentPage"] = h.page
ginH["pagination"] = pagination(h.page, h.totalPage, h.paginationStep, c.Request.URL.Path, q)
ginH["title"] = h.getTitle() ginH["title"] = h.getTitle()
ginH["pagination"] = pagination.NewParsePagination(totalRaw, h.pageSize, h.page, q, c.Request.URL.Path, h.paginationStep)
} }
var complie = regexp.MustCompile(`(/page)/(\d+)`)
type PaginationElements struct { type PaginationElements struct {
Prev string Prev string
Next string Next string
@ -265,113 +261,8 @@ type PaginationElements struct {
func getTemplateName() string { func getTemplateName() string {
tmlp := wpconfig.Options.Value("template") tmlp := wpconfig.Options.Value("template")
if i, err := templates.IsTemplateIsExist(tmlp); err != nil || !i { if i, err := theme.IsTemplateIsExist(tmlp); err != nil || !i {
tmlp = "twentyfifteen" tmlp = "twentyfifteen"
} }
return tmlp return tmlp
} }
var page = map[string]PaginationElements{
"twentyfifteen": {
Prev: "上一页",
Next: "下一页",
},
"twentyseventeen": {
Prev: `
<svg class="icon icon-arrow-left" aria-hidden="true" role="img"> <use href="#icon-arrow-left" xlink:href="#icon-arrow-left"></use> </svg>
<span class="screen-reader-text">上一页</span>
`,
Next: `
<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>`,
},
}
func pagination(currentPage, totalPage, step int, path, query string) (html string) {
if totalPage < 2 {
return
}
pathx := path
if !strings.Contains(path, "/page/") {
pathx = fmt.Sprintf("%s%s", path, "/page/1")
}
s := strings.Builder{}
if currentPage > totalPage {
currentPage = totalPage
}
r := complie
start := currentPage - step
end := currentPage + step
if start < 1 {
start = 1
}
if currentPage > 1 {
pp := ""
if currentPage >= 2 {
pp = replacePage(r, pathx, currentPage-1)
}
s.WriteString(fmt.Sprintf(`<a class="prev page-numbers" href="%s%s">%s</a>`, pp, query, page[getTemplateName()].Prev))
}
if currentPage >= step+2 {
d := ""
if currentPage > step+2 {
d = `<span class="page-numbers dots">…</span>`
}
e := replacePage(r, path, 1)
s.WriteString(fmt.Sprintf(`
<a class="page-numbers" href="%s%s"><span class="meta-nav screen-reader-text"> </span>1</a>
%s
`, e, query, d))
}
if totalPage < end {
end = totalPage
}
for page := start; page <= end; page++ {
h := ""
if currentPage == page {
h = fmt.Sprintf(`
<span aria-current="page" class="page-numbers current">
<span class="meta-nav screen-reader-text"> </span>%d</span>
`, page)
} else {
d := replacePage(r, pathx, page)
h = fmt.Sprintf(`
<a class="page-numbers" href="%s%s">
<span class="meta-nav screen-reader-text"> </span>%d</a>
`, d, query, page)
}
s.WriteString(h)
}
if totalPage >= currentPage+step+1 {
if totalPage > currentPage+step+1 {
s.WriteString(`<span class="page-numbers dots">…</span>`)
}
dd := replacePage(r, pathx, totalPage)
s.WriteString(fmt.Sprintf(`
<a class="page-numbers" href="%s%s"><span class="meta-nav screen-reader-text"> </span>%d</a>`, dd, query, totalPage))
}
if currentPage < totalPage {
dd := replacePage(r, pathx, currentPage+1)
s.WriteString(fmt.Sprintf(`<a class="next page-numbers" href="%s%s">%s</a>`, dd, query, page[getTemplateName()].Next))
}
html = s.String()
return
}
func replacePage(r *regexp.Regexp, path string, page int) (src string) {
if page == 1 {
src = r.ReplaceAllString(path, "")
} else {
s := fmt.Sprintf("$1/%d", page)
src = r.ReplaceAllString(path, s)
}
src = strings.Replace(src, "//", "/", -1)
if src == "" {
src = "/"
}
return
}

View File

@ -1,30 +0,0 @@
package theme
import (
"github.com/gin-gonic/gin"
"github/fthvgb1/wp-go/internal/plugins"
"github/fthvgb1/wp-go/internal/templates/twentyseventeen"
)
var themeMap = map[string]func(*gin.Context, gin.H, int) string{}
func InitTheme() {
HookFunc(twentyseventeen.ThemeName, twentyseventeen.Hook)
}
func HookFunc(themeName string, fn func(*gin.Context, gin.H, int) string) {
themeMap[themeName] = fn
}
func Hook(themeName string, c *gin.Context, h gin.H, scene int) string {
fn, ok := themeMap[themeName]
if ok && fn != nil {
return fn(c, h, scene)
}
if _, ok := plugins.IndexSceneMap[scene]; ok {
return "twentyfifteen/posts/index.gohtml"
} else if _, ok := plugins.DetailSceneMap[scene]; ok {
return "twentyfifteen/posts/detail.gohtml"
}
return "twentyfifteen/posts/detail.gohtml"
}

View File

@ -3,18 +3,17 @@ package main
import ( import (
"flag" "flag"
"fmt" "fmt"
"github/fthvgb1/wp-go/internal/actions" "github.com/fthvgb1/wp-go/internal/actions"
"github/fthvgb1/wp-go/internal/actions/theme" "github.com/fthvgb1/wp-go/internal/cmd/route"
"github/fthvgb1/wp-go/internal/cmd/route" "github.com/fthvgb1/wp-go/internal/mail"
"github/fthvgb1/wp-go/internal/mail" "github.com/fthvgb1/wp-go/internal/pkg/cache"
"github/fthvgb1/wp-go/internal/pkg/cache" "github.com/fthvgb1/wp-go/internal/pkg/config"
"github/fthvgb1/wp-go/internal/pkg/config" "github.com/fthvgb1/wp-go/internal/pkg/db"
"github/fthvgb1/wp-go/internal/pkg/db" "github.com/fthvgb1/wp-go/internal/pkg/logs"
"github/fthvgb1/wp-go/internal/pkg/logs" "github.com/fthvgb1/wp-go/internal/plugins"
"github/fthvgb1/wp-go/internal/plugins" "github.com/fthvgb1/wp-go/internal/theme"
"github/fthvgb1/wp-go/internal/templates" "github.com/fthvgb1/wp-go/internal/wpconfig"
"github/fthvgb1/wp-go/internal/wpconfig" "github.com/fthvgb1/wp-go/model"
"github/fthvgb1/wp-go/model"
"log" "log"
"math/rand" "math/rand"
"os" "os"
@ -48,8 +47,7 @@ func init() {
actions.InitFeed() actions.InitFeed()
cache.InitActionsCommonCache() cache.InitActionsCommonCache()
plugins.InitDigestCache() plugins.InitDigestCache()
templates.InitTemplateFunc() theme.InitThemeAndTemplateFuncMap()
theme.InitTheme()
go cronClearCache() go cronClearCache()
} }

View File

@ -0,0 +1,45 @@
package plugins
import "fmt"
type PageEle struct {
PrevEle string
NextEle string
DotsEle string
MiddleEle string
CurrentEle string
}
func TwentyFifteenPagination() PageEle {
return twentyFifteen
}
var twentyFifteen = PageEle{
PrevEle: `<a class="prev page-numbers" href="%s">上一页</a>`,
NextEle: `<a class="next page-numbers" href="%s">下一页</a>`,
DotsEle: `<span class="page-numbers dots">…</span>`,
MiddleEle: `<a class="page-numbers" href="%s"><span class="meta-nav screen-reader-text"> </span>%d</a>
`,
CurrentEle: `<span aria-current="page" class="page-numbers current">
<span class="meta-nav screen-reader-text"> </span>%d</span>`,
}
func (p PageEle) Current(page int) string {
return fmt.Sprintf(p.CurrentEle, page)
}
func (p PageEle) Prev(url string) string {
return fmt.Sprintf(p.PrevEle, url)
}
func (p PageEle) Next(url string) string {
return fmt.Sprintf(p.NextEle, url)
}
func (p PageEle) Dots() string {
return p.DotsEle
}
func (p PageEle) Middle(page int, url string) string {
return fmt.Sprintf(p.MiddleEle, url, page)
}

39
internal/theme/hook.go Normal file
View File

@ -0,0 +1,39 @@
package theme
import (
"github.com/fthvgb1/wp-go/internal/plugins"
"github.com/fthvgb1/wp-go/plugin/pagination"
"github.com/gin-gonic/gin"
)
var themeMap = map[string]func(int, *gin.Context, gin.H, int){}
func AddThemeHookFunc(name string, fn func(int, *gin.Context, gin.H, int)) {
if _, ok := themeMap[name]; ok {
panic("exists same name theme")
}
themeMap[name] = fn
}
func Hook(themeName string, status int, c *gin.Context, h gin.H, scene int) {
fn, ok := themeMap[themeName]
if ok && fn != nil {
fn(status, c, h, scene)
return
}
if _, ok := plugins.IndexSceneMap[scene]; ok {
p, ok := h["pagination"]
if ok {
pp, ok := p.(pagination.ParsePagination)
if ok {
h["pagination"] = pagination.Paginate(plugins.TwentyFifteenPagination(), pp)
}
}
c.HTML(status, "twentyfifteen/posts/index.gohtml", h)
return
} else if _, ok := plugins.DetailSceneMap[scene]; ok {
c.HTML(status, "twentyfifteen/posts/detail.gohtml", h)
return
}
c.HTML(status, "twentyfifteen/posts/index.gohtml", h)
}

9
internal/theme/theme.go Normal file
View File

@ -0,0 +1,9 @@
package theme
import (
"github.com/fthvgb1/wp-go/internal/theme/twentyseventeen"
)
func InitThemeAndTemplateFuncMap() {
AddThemeHookFunc(twentyseventeen.ThemeName, twentyseventeen.Hook)
}

View File

@ -0,0 +1,124 @@
package pagination
import (
"fmt"
"github.com/fthvgb1/wp-go/helper"
"math"
"regexp"
"strings"
)
type Elements interface {
Current(page int) string
Prev(url string) string
Next(url string) string
Dots() string
Middle(page int, url string) string
}
type ParsePagination struct {
Elements
TotalPage int
TotalRaw int
PageSize int
CurrentPage int
Query string
Path string
Step int
}
func NewParsePagination(totalRaw int, pageSize int, currentPage int, query string, path string, step int) ParsePagination {
allPage := int(math.Ceil(float64(totalRaw) / float64(pageSize)))
return ParsePagination{TotalPage: allPage, TotalRaw: totalRaw, PageSize: pageSize, CurrentPage: currentPage, Query: query, Path: path, Step: step}
}
func Paginate(e Elements, p ParsePagination) string {
p.Elements = e
return p.ToHtml()
}
var complie = regexp.MustCompile(`(/page)/(\d+)`)
func (p ParsePagination) ToHtml() (html string) {
if p.TotalRaw < 2 {
return
}
pathx := p.Path
if !strings.Contains(p.Path, "/page/") {
pathx = fmt.Sprintf("%s%s", p.Path, "/page/1")
}
s := strings.Builder{}
if p.CurrentPage > p.TotalPage {
p.CurrentPage = p.TotalPage
}
r := complie
start := p.CurrentPage - p.Step
end := p.CurrentPage + p.Step
if start < 1 {
start = 1
}
if p.CurrentPage > 1 {
pp := ""
if p.CurrentPage >= 2 {
pp = replacePage(r, pathx, p.CurrentPage-1)
}
s.WriteString(p.Prev(helper.StrJoin(pp, p.Query)))
}
if p.CurrentPage >= p.Step+2 {
d := false
if p.CurrentPage > p.Step+2 {
d = true
}
e := replacePage(r, p.Path, 1)
s.WriteString(p.Middle(1, helper.StrJoin(e, p.Query)))
if d {
s.WriteString(p.Dots())
}
}
if p.TotalPage < end {
end = p.TotalPage
}
for page := start; page <= end; page++ {
h := ""
if p.CurrentPage == page {
h = p.Current(page)
} else {
d := replacePage(r, pathx, page)
h = p.Middle(page, helper.StrJoin(d, p.Query))
}
s.WriteString(h)
}
if p.TotalPage >= p.CurrentPage+p.Step+1 {
d := false
if p.TotalPage > p.CurrentPage+p.Step+1 {
d = true
}
dd := replacePage(r, pathx, p.TotalPage)
if d {
s.WriteString(p.Dots())
}
s.WriteString(p.Middle(p.TotalPage, helper.StrJoin(dd, p.Query)))
}
if p.CurrentPage < p.TotalPage {
dd := replacePage(r, pathx, p.CurrentPage+1)
s.WriteString(p.Next(helper.StrJoin(dd, p.Query)))
}
html = s.String()
return
}
func replacePage(r *regexp.Regexp, path string, page int) (src string) {
if page == 1 {
src = r.ReplaceAllString(path, "")
} else {
s := fmt.Sprintf("$1/%d", page)
src = r.ReplaceAllString(path, s)
}
src = strings.Replace(src, "//", "/", -1)
if src == "" {
src = "/"
}
return
}