This commit is contained in:
xing 2022-09-23 21:46:34 +08:00
parent ddc64028bb
commit 13e3b4804e
9 changed files with 205 additions and 3 deletions

View File

@ -8,6 +8,7 @@ import (
"github/fthvgb1/wp-go/actions/common" "github/fthvgb1/wp-go/actions/common"
"github/fthvgb1/wp-go/helper" "github/fthvgb1/wp-go/helper"
"github/fthvgb1/wp-go/models" "github/fthvgb1/wp-go/models"
"github/fthvgb1/wp-go/plugins"
"math/rand" "math/rand"
"net/http" "net/http"
"net/url" "net/url"
@ -78,6 +79,7 @@ func Detail(c *gin.Context) {
common.PasswdProjectContent(&post) common.PasswdProjectContent(&post)
showComment = false showComment = false
} }
plugins.ApplyPlugin(plugins.NewPostPlugin(c, plugins.Detail), &post)
comments, err := common.PostComments(ctx, post.Id) comments, err := common.PostComments(ctx, post.Id)
commentss := treeComments(comments) commentss := treeComments(comments)
prev, next, err := common.GetContextPost(post.Id, post.PostDate) prev, next, err := common.GetContextPost(post.Id, post.PostDate)

View File

@ -8,6 +8,7 @@ import (
"github/fthvgb1/wp-go/actions/common" "github/fthvgb1/wp-go/actions/common"
"github/fthvgb1/wp-go/helper" "github/fthvgb1/wp-go/helper"
"github/fthvgb1/wp-go/models" "github/fthvgb1/wp-go/models"
"github/fthvgb1/wp-go/plugins"
"math" "math"
"net/http" "net/http"
"regexp" "regexp"
@ -35,6 +36,7 @@ type indexHandle struct {
status []any status []any
header string header string
paginationStep int paginationStep int
scene uint
} }
func newIndexHandle(ctx *gin.Context) *indexHandle { func newIndexHandle(ctx *gin.Context) *indexHandle {
@ -54,6 +56,7 @@ func newIndexHandle(ctx *gin.Context) *indexHandle {
join: models.SqlBuilder{}, join: models.SqlBuilder{},
postType: []any{"post"}, postType: []any{"post"},
status: []any{"publish"}, status: []any{"publish"},
scene: plugins.Home,
} }
} }
func (h *indexHandle) setTitleLR(l, r string) { func (h *indexHandle) setTitleLR(l, r string) {
@ -85,6 +88,7 @@ func (h *indexHandle) parseParams() {
ss := fmt.Sprintf("%s年%s月", year, strings.TrimLeft(month, "0")) ss := fmt.Sprintf("%s年%s月", year, strings.TrimLeft(month, "0"))
h.header = fmt.Sprintf("月度归档: <span>%s</span>", ss) h.header = fmt.Sprintf("月度归档: <span>%s</span>", ss)
h.setTitleLR(ss, models.Options["blogname"]) h.setTitleLR(ss, models.Options["blogname"])
h.scene = plugins.Archive
} }
category := h.c.Param("category") category := h.c.Param("category")
if category == "" { if category == "" {
@ -111,6 +115,7 @@ func (h *indexHandle) parseParams() {
"left join", "wp_terms d", "c.term_id=d.term_id", "left join", "wp_terms d", "c.term_id=d.term_id",
}) })
h.setTitleLR(category, models.Options["blogname"]) h.setTitleLR(category, models.Options["blogname"])
h.scene = plugins.Category
} }
s := h.c.Query("s") s := h.c.Query("s")
if s != "" && strings.Replace(s, " ", "", -1) != "" { if s != "" && strings.Replace(s, " ", "", -1) != "" {
@ -124,6 +129,7 @@ func (h *indexHandle) parseParams() {
h.header = fmt.Sprintf("%s的搜索结果", s) h.header = fmt.Sprintf("%s的搜索结果", s)
h.setTitleLR(helper.StrJoin(`"`, s, `"`, "的搜索结果"), models.Options["blogname"]) h.setTitleLR(helper.StrJoin(`"`, s, `"`, "的搜索结果"), models.Options["blogname"])
h.search = s h.search = s
h.scene = plugins.Search
} else { } else {
h.status = append(h.status, "private") h.status = append(h.status, "private")
} }
@ -179,6 +185,8 @@ func Index(c *gin.Context) {
} }
err = common.QueryAndSetPostCache(postIds) err = common.QueryAndSetPostCache(postIds)
pw := h.session.Get("post_password") pw := h.session.Get("post_password")
c.Set("post_password", pw)
plug := plugins.NewPostPlugin(c, h.scene)
for i, v := range postIds { for i, v := range postIds {
post, _ := common.PostsCache.Load(v.Id) post, _ := common.PostsCache.Load(v.Id)
pp := post.(*models.WpPosts) pp := post.(*models.WpPosts)
@ -188,8 +196,11 @@ func Index(c *gin.Context) {
common.PasswdProjectContent(&px) common.PasswdProjectContent(&px)
} }
postIds[i] = px postIds[i] = px
plugins.ApplyPlugin(plug, &postIds[i])
} }
for i, post := range recent { for i, post := range recent {
if post.PostPassword != "" && pw != post.PostPassword { if post.PostPassword != "" && pw != post.PostPassword {
common.PasswdProjectContent(&recent[i]) common.PasswdProjectContent(&recent[i])
} }
@ -201,6 +212,8 @@ func Index(c *gin.Context) {
ginH["title"] = h.getTitle() ginH["title"] = h.getTitle()
} }
var complie = regexp.MustCompile(`(/page)/(\d+)`)
func pagination(currentPage, totalPage, step int, path, query string) (html string) { func pagination(currentPage, totalPage, step int, path, query string) (html string) {
if totalPage < 2 { if totalPage < 2 {
return return
@ -213,7 +226,7 @@ func pagination(currentPage, totalPage, step int, path, query string) (html stri
if currentPage > totalPage { if currentPage > totalPage {
currentPage = totalPage currentPage = totalPage
} }
r := regexp.MustCompile(`(/page)/(\d+)`) r := complie
start := currentPage - step start := currentPage - step
end := currentPage + step end := currentPage + step
if start < 1 { if start < 1 {

1
go.mod
View File

@ -11,6 +11,7 @@ require (
) )
require ( require (
github.com/dlclark/regexp2 v1.7.0 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-playground/locales v0.14.0 // indirect github.com/go-playground/locales v0.14.0 // indirect
github.com/go-playground/universal-translator v0.18.0 // indirect github.com/go-playground/universal-translator v0.18.0 // indirect

View File

@ -3,8 +3,10 @@ package helper
import ( import (
"crypto/md5" "crypto/md5"
"fmt" "fmt"
"github.com/dlclark/regexp2"
"io" "io"
"reflect" "reflect"
"regexp"
"strings" "strings"
) )
@ -64,6 +66,39 @@ func SlicePagination[T any](arr []T, page, pageSize int) []T {
func StringMd5(str string) string { func StringMd5(str string) string {
h := md5.New() h := md5.New()
io.WriteString(h, str) _, err := io.WriteString(h, str)
if err != nil {
return ""
}
return fmt.Sprintf("%x", h.Sum(nil)) return fmt.Sprintf("%x", h.Sum(nil))
} }
var allHtmlTag = regexp.MustCompile("</?.*>")
func StripTags(str, allowable string) string {
html := ""
if allowable == "" {
return allHtmlTag.ReplaceAllString(str, "")
}
r := strings.Split(allowable, ">")
re := ""
for _, reg := range r {
if reg == "" {
continue
}
tag := strings.TrimLeft(reg, "<")
ree := fmt.Sprintf(`%s|\/%s`, tag, tag)
re = fmt.Sprintf("%s|%s", re, ree)
}
ree := strings.Trim(re, "|")
reg := fmt.Sprintf("<(?!%s).*?>", ree)
compile, err := regexp2.Compile(reg, regexp2.IgnoreCase)
if err != nil {
return str
}
html, err = compile.Replace(str, "", 0, -1)
if err != nil {
return str
}
return html
}

View File

@ -196,3 +196,31 @@ func TestSlicePagination(t *testing.T) {
}) })
} }
} }
func TestStripTags(t *testing.T) {
type args struct {
str string
allowable string
}
tests := []struct {
name string
args args
want string
}{
{
name: "t1",
args: args{
str: "<p>ppppp<span>ffff</span></p><img />",
allowable: "<p><img>",
},
want: "<p>pppppffff</p><img />",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := StripTags(tt.args.str, tt.args.allowable); got != tt.want {
t.Errorf("StripTags() = %v, want %v", got, tt.want)
}
})
}
}

View File

@ -13,19 +13,23 @@ func init() {
if err != nil { if err != nil {
panic(err) panic(err)
} }
common.InitCache()
err = db.InitDb() err = db.InitDb()
if err != nil { if err != nil {
panic(err) panic(err)
} }
err = models.InitOptions() err = models.InitOptions()
if err != nil { if err != nil {
panic(err) panic(err)
} }
err = models.InitTerms() err = models.InitTerms()
if err != nil { if err != nil {
panic(err) panic(err)
} }
common.InitCache()
} }
func main() { func main() {

63
plugins/Excerpt.go Normal file
View File

@ -0,0 +1,63 @@
package plugins
import (
"fmt"
"github.com/gin-gonic/gin"
"github/fthvgb1/wp-go/helper"
"github/fthvgb1/wp-go/models"
"regexp"
"strings"
"unicode/utf8"
)
var removeWpBlock = regexp.MustCompile("<!-- /?wp:.*-->")
var more = regexp.MustCompile("<!--more(.*?)?-->")
var tag = regexp.MustCompile(`<.*?>`)
var limit = 300
func ExceptRaw(str string, limit, id int) string {
if r := more.FindString(str); r != "" {
m := strings.Split(str, r)
str = m[0]
return ""
}
content := removeWpBlock.ReplaceAllString(str, "")
content = strings.Trim(content, " \t\n\r\000\x0B")
content = strings.Replace(content, "]]>", "]]&gt;", -1)
content = helper.StripTags(content, "<a><b><blockquote><br><cite><code><dd><del><div><dl><dt><em><h1><h2><h3><h4><h5><h6><i><img><li><ol><p><pre><span><strong><ul>")
length := utf8.RuneCountInString(content) + 1
if length > limit {
start, l := 0, limit+1
end := l
for {
txt := string([]rune(content)[start:end])
count := 0
for _, ints := range tag.FindAllStringIndex(txt, -1) {
t := []rune(content[ints[0]:ints[1]])
count += len(t)
l += len(t)
}
if count > 0 && length > l {
start = end
end += count
} else if count > 0 && length < l {
break
} else {
content = string([]rune(content)[:end])
content = fmt.Sprintf(`%s...<p class="read-more"><a href="/p/%d">继续阅读</a></p>`, content, id)
break
}
}
}
return content
}
func Except(p *Plugin[models.WpPosts], c *gin.Context, post *models.WpPosts, scene uint) {
if scene == Detail {
return
}
post.PostContent = ExceptRaw(post.PostContent, limit, int(post.Id))
}

38
plugins/plugins.go Normal file
View File

@ -0,0 +1,38 @@
package plugins
import (
"github.com/gin-gonic/gin"
)
const (
Home = iota + 1
Archive
Category
Search
Detail
)
type PluginFunc[T any] func(*Plugin[T], *gin.Context, *T, uint)
type Plugin[T any] struct {
calls []PluginFunc[T]
index int
post *T
scene uint
c *gin.Context
}
func NewPlugin[T any](calls []PluginFunc[T], index int, post *T, scene uint, c *gin.Context) *Plugin[T] {
return &Plugin[T]{calls: calls, index: index, post: post, scene: scene, c: c}
}
func (p *Plugin[T]) Push(call ...PluginFunc[T]) {
p.calls = append(p.calls, call...)
}
func (p *Plugin[T]) Next() {
p.index++
for ; p.index < len(p.calls); p.index++ {
p.calls[p.index](p, p.c, p.post, p.scene)
}
}

18
plugins/posts.go Normal file
View File

@ -0,0 +1,18 @@
package plugins
import (
"github.com/gin-gonic/gin"
"github/fthvgb1/wp-go/models"
)
func NewPostPlugin(ctx *gin.Context, scene uint) *Plugin[models.WpPosts] {
p := NewPlugin[models.WpPosts](nil, -1, nil, scene, ctx)
p.Push(Except)
return p
}
func ApplyPlugin(p *Plugin[models.WpPosts], post *models.WpPosts) {
p.post = post
p.Next()
p.index = -1
}