分页器调整及主题hook机制
This commit is contained in:
parent
86adc60c51
commit
b8cf654130
|
@ -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
|
|
||||||
}
|
|
||||||
|
|
|
@ -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"
|
|
||||||
}
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
45
internal/plugins/pagination.go
Normal file
45
internal/plugins/pagination.go
Normal 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
39
internal/theme/hook.go
Normal 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
9
internal/theme/theme.go
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
package theme
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/fthvgb1/wp-go/internal/theme/twentyseventeen"
|
||||||
|
)
|
||||||
|
|
||||||
|
func InitThemeAndTemplateFuncMap() {
|
||||||
|
AddThemeHookFunc(twentyseventeen.ThemeName, twentyseventeen.Hook)
|
||||||
|
}
|
124
plugin/pagination/pagination.go
Normal file
124
plugin/pagination/pagination.go
Normal 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
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user