twentyseventeen 主题 header 图
This commit is contained in:
parent
470312936c
commit
a748d53f5a
1
go.mod
1
go.mod
|
@ -16,6 +16,7 @@ require (
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/elliotchance/phpserialize v1.3.3 // 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
|
||||||
|
|
2
go.sum
2
go.sum
|
@ -4,6 +4,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo=
|
github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo=
|
||||||
github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||||
|
github.com/elliotchance/phpserialize v1.3.3 h1:hV4QVmGdCiYgoBbw+ADt6fNgyZ2mYX0OgpnON1adTCM=
|
||||||
|
github.com/elliotchance/phpserialize v1.3.3/go.mod h1:gt7XX9+ETUcLXbtTKEuyrqW3lcLUAeS/AnGZ2e49TZs=
|
||||||
github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4=
|
github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4=
|
||||||
github.com/gin-contrib/gzip v0.0.6/go.mod h1:QOJlmV2xmayAjkNS2Y8NQsMneuRShOU/kjovCXNuzzk=
|
github.com/gin-contrib/gzip v0.0.6/go.mod h1:QOJlmV2xmayAjkNS2Y8NQsMneuRShOU/kjovCXNuzzk=
|
||||||
github.com/gin-contrib/pprof v1.4.0 h1:XxiBSf5jWZ5i16lNOPbMTVdgHBdhfGRD5PZ1LWazzvg=
|
github.com/gin-contrib/pprof v1.4.0 h1:XxiBSf5jWZ5i16lNOPbMTVdgHBdhfGRD5PZ1LWazzvg=
|
||||||
|
|
|
@ -2,7 +2,7 @@ package helper
|
||||||
|
|
||||||
import "encoding/json"
|
import "encoding/json"
|
||||||
|
|
||||||
func MapToStruct[T any, M any](m M) (r T, err error) {
|
func StrAnyMapToStruct[T any, M any](m M) (r T, err error) {
|
||||||
str, err := json.Marshal(m)
|
str, err := json.Marshal(m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
@ -11,12 +11,12 @@ func MapToStruct[T any, M any](m M) (r T, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func StructToMap[T any](s T) (r map[string]any, err error) {
|
func StructToAnyMap[K comparable, T any](s T) (r map[K]any, err error) {
|
||||||
marshal, err := json.Marshal(s)
|
marshal, err := json.Marshal(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r = make(map[string]any)
|
r = make(map[K]any)
|
||||||
err = json.Unmarshal(marshal, &r)
|
err = json.Unmarshal(marshal, &r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -31,16 +31,15 @@ func MapToSlice[T any, K comparable, V any](m map[K]V, fn func(K, V) (T, bool))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func MapAnyToString(m map[any]any) (r map[string]any) {
|
// MapAnyAnyToStrAny map[any]any => map[string]any 方便json转换
|
||||||
|
func MapAnyAnyToStrAny(m map[any]any) (r map[string]any) {
|
||||||
r = make(map[string]any)
|
r = make(map[string]any)
|
||||||
for k, v := range m {
|
for k, v := range m {
|
||||||
kk, ok := k.(string)
|
kk, ok := k.(string)
|
||||||
if ok {
|
if ok {
|
||||||
vv, ok := v.(map[any]any)
|
vv, ok := v.(map[any]any)
|
||||||
if ok {
|
if ok {
|
||||||
x := make(map[string]any)
|
r[kk] = MapAnyAnyToStrAny(vv)
|
||||||
MapAnyToString(vv)
|
|
||||||
r[kk] = x
|
|
||||||
} else {
|
} else {
|
||||||
r[kk] = v
|
r[kk] = v
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ type Me struct {
|
||||||
Null any
|
Null any
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMapToStruct(t *testing.T) {
|
func TestStrAnyMapToStruct(t *testing.T) {
|
||||||
type args struct {
|
type args struct {
|
||||||
m map[string]any
|
m map[string]any
|
||||||
}
|
}
|
||||||
|
@ -60,19 +60,19 @@ func TestMapToStruct(t *testing.T) {
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
gotR, err := MapToStruct[Me](tt.args.m)
|
gotR, err := StrAnyMapToStruct[Me](tt.args.m)
|
||||||
if (err != nil) != tt.wantErr {
|
if (err != nil) != tt.wantErr {
|
||||||
t.Errorf("MapToStruct() error = %v, wantErr %v", err, tt.wantErr)
|
t.Errorf("StrAnyMapToStruct() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(gotR, tt.wantR) {
|
if !reflect.DeepEqual(gotR, tt.wantR) {
|
||||||
t.Errorf("MapToStruct() gotR = %v, want %v", gotR, tt.wantR)
|
t.Errorf("StrAnyMapToStruct() gotR = %v, want %v", gotR, tt.wantR)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStructToMap(t *testing.T) {
|
func TestStructToAnyMap(t *testing.T) {
|
||||||
type args[T any] struct {
|
type args[T any] struct {
|
||||||
s T
|
s T
|
||||||
}
|
}
|
||||||
|
@ -113,13 +113,13 @@ func TestStructToMap(t *testing.T) {
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
gotR, err := StructToMap[Me](tt.args.s)
|
gotR, err := StructToAnyMap[string, Me](tt.args.s)
|
||||||
if (err != nil) != tt.wantErr {
|
if (err != nil) != tt.wantErr {
|
||||||
t.Errorf("StructToMap() error = %v, wantErr %v", err, tt.wantErr)
|
t.Errorf("StructToAnyMap() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(gotR, tt.wantR) {
|
if !reflect.DeepEqual(gotR, tt.wantR) {
|
||||||
t.Errorf("StructToMap() gotR = %v, want %v", gotR, tt.wantR)
|
t.Errorf("StructToAnyMap() gotR = %v, want %v", gotR, tt.wantR)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"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/helper"
|
||||||
|
"github/fthvgb1/wp-go/internal/actions/theme"
|
||||||
cache2 "github/fthvgb1/wp-go/internal/pkg/cache"
|
cache2 "github/fthvgb1/wp-go/internal/pkg/cache"
|
||||||
dao "github/fthvgb1/wp-go/internal/pkg/dao"
|
dao "github/fthvgb1/wp-go/internal/pkg/dao"
|
||||||
"github/fthvgb1/wp-go/internal/pkg/models"
|
"github/fthvgb1/wp-go/internal/pkg/models"
|
||||||
|
@ -202,7 +203,9 @@ func Index(c *gin.Context) {
|
||||||
stat = http.StatusInternalServerError
|
stat = http.StatusInternalServerError
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.HTML(stat, helper.StrJoin(getTemplateName(), "/posts/index.gohtml"), ginH)
|
t := getTemplateName()
|
||||||
|
tmlp := theme.Hook(t, c, ginH, int(h.scene))
|
||||||
|
c.HTML(stat, tmlp, ginH)
|
||||||
}()
|
}()
|
||||||
err = h.parseParams()
|
err = h.parseParams()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -224,6 +227,7 @@ func Index(c *gin.Context) {
|
||||||
}
|
}
|
||||||
if len(postIds) < 1 && h.category != "" {
|
if len(postIds) < 1 && h.category != "" {
|
||||||
h.titleL = "未找到页面"
|
h.titleL = "未找到页面"
|
||||||
|
h.scene = plugins.Empty404
|
||||||
}
|
}
|
||||||
|
|
||||||
pw := h.session.Get("post_password")
|
pw := h.session.Get("post_password")
|
||||||
|
@ -247,6 +251,7 @@ 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["pagination"] = pagination(h.page, h.totalPage, h.paginationStep, c.Request.URL.Path, q)
|
ginH["pagination"] = pagination(h.page, h.totalPage, h.paginationStep, c.Request.URL.Path, q)
|
||||||
ginH["title"] = h.getTitle()
|
ginH["title"] = h.getTitle()
|
||||||
}
|
}
|
||||||
|
|
30
internal/actions/theme/theme.go
Normal file
30
internal/actions/theme/theme.go
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
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"
|
||||||
|
}
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github/fthvgb1/wp-go/internal/actions"
|
"github/fthvgb1/wp-go/internal/actions"
|
||||||
|
"github/fthvgb1/wp-go/internal/actions/theme"
|
||||||
"github/fthvgb1/wp-go/internal/cmd/route"
|
"github/fthvgb1/wp-go/internal/cmd/route"
|
||||||
"github/fthvgb1/wp-go/internal/mail"
|
"github/fthvgb1/wp-go/internal/mail"
|
||||||
"github/fthvgb1/wp-go/internal/pkg/cache"
|
"github/fthvgb1/wp-go/internal/pkg/cache"
|
||||||
|
@ -11,6 +12,7 @@ import (
|
||||||
"github/fthvgb1/wp-go/internal/pkg/db"
|
"github/fthvgb1/wp-go/internal/pkg/db"
|
||||||
"github/fthvgb1/wp-go/internal/pkg/logs"
|
"github/fthvgb1/wp-go/internal/pkg/logs"
|
||||||
"github/fthvgb1/wp-go/internal/plugins"
|
"github/fthvgb1/wp-go/internal/plugins"
|
||||||
|
"github/fthvgb1/wp-go/internal/templates"
|
||||||
"github/fthvgb1/wp-go/internal/wpconfig"
|
"github/fthvgb1/wp-go/internal/wpconfig"
|
||||||
"github/fthvgb1/wp-go/model"
|
"github/fthvgb1/wp-go/model"
|
||||||
"log"
|
"log"
|
||||||
|
@ -46,6 +48,8 @@ func init() {
|
||||||
actions.InitFeed()
|
actions.InitFeed()
|
||||||
cache.InitActionsCommonCache()
|
cache.InitActionsCommonCache()
|
||||||
plugins.InitDigestCache()
|
plugins.InitDigestCache()
|
||||||
|
templates.InitTemplateFunc()
|
||||||
|
theme.InitTheme()
|
||||||
go cronClearCache()
|
go cronClearCache()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,10 +11,7 @@ import (
|
||||||
"github/fthvgb1/wp-go/internal/pkg/config"
|
"github/fthvgb1/wp-go/internal/pkg/config"
|
||||||
"github/fthvgb1/wp-go/internal/static"
|
"github/fthvgb1/wp-go/internal/static"
|
||||||
"github/fthvgb1/wp-go/internal/templates"
|
"github/fthvgb1/wp-go/internal/templates"
|
||||||
"github/fthvgb1/wp-go/internal/wpconfig"
|
|
||||||
"html/template"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func SetupRouter() (*gin.Engine, func()) {
|
func SetupRouter() (*gin.Engine, func()) {
|
||||||
|
@ -29,17 +26,7 @@ func SetupRouter() (*gin.Engine, func()) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r.HTMLRender = templates.NewFsTemplate(template.FuncMap{
|
r.HTMLRender = templates.NewFsTemplate(templates.FuncMap()).SetTemplate()
|
||||||
"unescaped": func(s string) any {
|
|
||||||
return template.HTML(s)
|
|
||||||
},
|
|
||||||
"dateCh": func(t time.Time) any {
|
|
||||||
return t.Format("2006年 01月 02日")
|
|
||||||
},
|
|
||||||
"getOption": func(k string) string {
|
|
||||||
return wpconfig.Options.Value(k)
|
|
||||||
},
|
|
||||||
}).SetTemplate()
|
|
||||||
validServerName, reloadValidServerNameFn := middleware.ValidateServerNames()
|
validServerName, reloadValidServerNameFn := middleware.ValidateServerNames()
|
||||||
fl, flReload := middleware.FlowLimit(c.MaxRequestSleepNum, c.MaxRequestNum, c.SleepTime)
|
fl, flReload := middleware.FlowLimit(c.MaxRequestSleepNum, c.MaxRequestNum, c.SleepTime)
|
||||||
r.Use(
|
r.Use(
|
||||||
|
|
40
internal/pkg/cache/cache.go
vendored
40
internal/pkg/cache/cache.go
vendored
|
@ -6,18 +6,18 @@ import (
|
||||||
"github/fthvgb1/wp-go/internal/pkg/config"
|
"github/fthvgb1/wp-go/internal/pkg/config"
|
||||||
"github/fthvgb1/wp-go/internal/pkg/dao"
|
"github/fthvgb1/wp-go/internal/pkg/dao"
|
||||||
"github/fthvgb1/wp-go/internal/pkg/logs"
|
"github/fthvgb1/wp-go/internal/pkg/logs"
|
||||||
models2 "github/fthvgb1/wp-go/internal/pkg/models"
|
"github/fthvgb1/wp-go/internal/pkg/models"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
var postContextCache *cache.MapCache[uint64, common.PostContext]
|
var postContextCache *cache.MapCache[uint64, common.PostContext]
|
||||||
var archivesCaches *Arch
|
var archivesCaches *Arch
|
||||||
var categoryCaches *cache.SliceCache[models2.TermsMy]
|
var categoryCaches *cache.SliceCache[models.TermsMy]
|
||||||
var recentPostsCaches *cache.SliceCache[models2.Posts]
|
var recentPostsCaches *cache.SliceCache[models.Posts]
|
||||||
var recentCommentsCaches *cache.SliceCache[models2.Comments]
|
var recentCommentsCaches *cache.SliceCache[models.Comments]
|
||||||
var postCommentCaches *cache.MapCache[uint64, []uint64]
|
var postCommentCaches *cache.MapCache[uint64, []uint64]
|
||||||
var postsCache *cache.MapCache[uint64, models2.Posts]
|
var postsCache *cache.MapCache[uint64, models.Posts]
|
||||||
|
|
||||||
var postMetaCache *cache.MapCache[uint64, map[string]any]
|
var postMetaCache *cache.MapCache[uint64, map[string]any]
|
||||||
|
|
||||||
|
@ -26,9 +26,9 @@ var postListIdsCache *cache.MapCache[string, common.PostIds]
|
||||||
var searchPostIdsCache *cache.MapCache[string, common.PostIds]
|
var searchPostIdsCache *cache.MapCache[string, common.PostIds]
|
||||||
var maxPostIdCache *cache.SliceCache[uint64]
|
var maxPostIdCache *cache.SliceCache[uint64]
|
||||||
|
|
||||||
var usersCache *cache.MapCache[uint64, models2.Users]
|
var usersCache *cache.MapCache[uint64, models.Users]
|
||||||
var usersNameCache *cache.MapCache[string, models2.Users]
|
var usersNameCache *cache.MapCache[string, models.Users]
|
||||||
var commentsCache *cache.MapCache[uint64, models2.Comments]
|
var commentsCache *cache.MapCache[uint64, models.Comments]
|
||||||
|
|
||||||
func InitActionsCommonCache() {
|
func InitActionsCommonCache() {
|
||||||
c := config.Conf.Load()
|
c := config.Conf.Load()
|
||||||
|
@ -45,25 +45,25 @@ func InitActionsCommonCache() {
|
||||||
|
|
||||||
postContextCache = cache.NewMapCacheByFn[uint64, common.PostContext](common.GetPostContext, c.ContextPostCacheTime)
|
postContextCache = cache.NewMapCacheByFn[uint64, common.PostContext](common.GetPostContext, c.ContextPostCacheTime)
|
||||||
|
|
||||||
postsCache = cache.NewMapCacheByBatchFn[uint64, models2.Posts](common.GetPostsByIds, c.PostDataCacheTime)
|
postsCache = cache.NewMapCacheByBatchFn[uint64, models.Posts](common.GetPostsByIds, c.PostDataCacheTime)
|
||||||
|
|
||||||
postMetaCache = cache.NewMapCacheByBatchFn[uint64, map[string]any](common.GetPostMetaByPostIds, c.PostDataCacheTime)
|
postMetaCache = cache.NewMapCacheByBatchFn[uint64, map[string]any](common.GetPostMetaByPostIds, c.PostDataCacheTime)
|
||||||
|
|
||||||
categoryCaches = cache.NewSliceCache[models2.TermsMy](common.Categories, c.CategoryCacheTime)
|
categoryCaches = cache.NewSliceCache[models.TermsMy](common.Categories, c.CategoryCacheTime)
|
||||||
|
|
||||||
recentPostsCaches = cache.NewSliceCache[models2.Posts](common.RecentPosts, c.RecentPostCacheTime)
|
recentPostsCaches = cache.NewSliceCache[models.Posts](common.RecentPosts, c.RecentPostCacheTime)
|
||||||
|
|
||||||
recentCommentsCaches = cache.NewSliceCache[models2.Comments](common.RecentComments, c.RecentCommentsCacheTime)
|
recentCommentsCaches = cache.NewSliceCache[models.Comments](common.RecentComments, c.RecentCommentsCacheTime)
|
||||||
|
|
||||||
postCommentCaches = cache.NewMapCacheByFn[uint64, []uint64](common.PostComments, c.PostCommentsCacheTime)
|
postCommentCaches = cache.NewMapCacheByFn[uint64, []uint64](common.PostComments, c.PostCommentsCacheTime)
|
||||||
|
|
||||||
maxPostIdCache = cache.NewSliceCache[uint64](common.GetMaxPostId, c.MaxPostIdCacheTime)
|
maxPostIdCache = cache.NewSliceCache[uint64](common.GetMaxPostId, c.MaxPostIdCacheTime)
|
||||||
|
|
||||||
usersCache = cache.NewMapCacheByFn[uint64, models2.Users](common.GetUserById, c.UserInfoCacheTime)
|
usersCache = cache.NewMapCacheByFn[uint64, models.Users](common.GetUserById, c.UserInfoCacheTime)
|
||||||
|
|
||||||
usersNameCache = cache.NewMapCacheByFn[string, models2.Users](common.GetUserByName, c.UserInfoCacheTime)
|
usersNameCache = cache.NewMapCacheByFn[string, models.Users](common.GetUserByName, c.UserInfoCacheTime)
|
||||||
|
|
||||||
commentsCache = cache.NewMapCacheByBatchFn[uint64, models2.Comments](common.GetCommentByIds, c.CommentsCacheTime)
|
commentsCache = cache.NewMapCacheByBatchFn[uint64, models.Comments](common.GetCommentByIds, c.CommentsCacheTime)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ClearCache() {
|
func ClearCache() {
|
||||||
|
@ -89,18 +89,18 @@ func FlushCache() {
|
||||||
usersCache.Flush()
|
usersCache.Flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
func Archives(ctx context.Context) (r []models2.PostArchive) {
|
func Archives(ctx context.Context) (r []models.PostArchive) {
|
||||||
return archivesCaches.getArchiveCache(ctx)
|
return archivesCaches.getArchiveCache(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Arch struct {
|
type Arch struct {
|
||||||
data []models2.PostArchive
|
data []models.PostArchive
|
||||||
mutex *sync.Mutex
|
mutex *sync.Mutex
|
||||||
setCacheFunc func(context.Context) ([]models2.PostArchive, error)
|
setCacheFunc func(context.Context) ([]models.PostArchive, error)
|
||||||
month time.Month
|
month time.Month
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Arch) getArchiveCache(ctx context.Context) []models2.PostArchive {
|
func (c *Arch) getArchiveCache(ctx context.Context) []models.PostArchive {
|
||||||
l := len(c.data)
|
l := len(c.data)
|
||||||
m := time.Now().Month()
|
m := time.Now().Month()
|
||||||
if l > 0 && c.month != m || l < 1 {
|
if l > 0 && c.month != m || l < 1 {
|
||||||
|
@ -117,7 +117,7 @@ func (c *Arch) getArchiveCache(ctx context.Context) []models2.PostArchive {
|
||||||
return c.data
|
return c.data
|
||||||
}
|
}
|
||||||
|
|
||||||
func Categories(ctx context.Context) []models2.TermsMy {
|
func Categories(ctx context.Context) []models.TermsMy {
|
||||||
r, err := categoryCaches.GetCache(ctx, time.Second, ctx)
|
r, err := categoryCaches.GetCache(ctx, time.Second, ctx)
|
||||||
logs.ErrPrintln(err, "get category ")
|
logs.ErrPrintln(err, "get category ")
|
||||||
return r
|
return r
|
||||||
|
|
|
@ -44,50 +44,53 @@ func GetPostMetaByPostIds(args ...any) (r map[uint64]map[string]any, err error)
|
||||||
func ToPostThumb(c context.Context, meta map[string]any, host string) (r models.PostThumbnail) {
|
func ToPostThumb(c context.Context, meta map[string]any, host string) (r models.PostThumbnail) {
|
||||||
if meta != nil {
|
if meta != nil {
|
||||||
m, ok := meta["_thumbnail_id"]
|
m, ok := meta["_thumbnail_id"]
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
id, err := strconv.ParseUint(m.(string), 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
mx, err := GetPostMetaByPostIds(c, []uint64{id})
|
||||||
|
if err != nil || mx == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
mm, ok := mx[id]
|
||||||
|
if !ok || mm == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
x, ok := mm["_wp_attachment_metadata"]
|
||||||
if ok {
|
if ok {
|
||||||
id, err := strconv.ParseUint(m.(string), 10, 64)
|
metadata, ok := x.(models.WpAttachmentMetadata)
|
||||||
if err == nil {
|
if ok {
|
||||||
mx, err := GetPostMetaByPostIds(c, []uint64{id})
|
r = thumbnail(metadata, "post-thumbnail", host)
|
||||||
if err == nil && mx != nil {
|
|
||||||
mm, ok := mx[id]
|
|
||||||
if ok && mm != nil {
|
|
||||||
f, ok := mm["_wp_attached_file"]
|
|
||||||
if ok {
|
|
||||||
ff, ok := f.(string)
|
|
||||||
if ok && ff != "" {
|
|
||||||
r.Path = ff
|
|
||||||
}
|
|
||||||
}
|
|
||||||
x, ok := mm["_wp_attachment_metadata"]
|
|
||||||
if ok {
|
|
||||||
metadata, ok := x.(models.WpAttachmentMetadata)
|
|
||||||
if ok {
|
|
||||||
if _, ok := metadata.Sizes["post-thumbnail"]; ok {
|
|
||||||
r.Width = metadata.Sizes["post-thumbnail"].Width
|
|
||||||
r.Height = metadata.Sizes["post-thumbnail"].Height
|
|
||||||
up := strings.Split(metadata.File, "/")
|
|
||||||
r.Srcset = strings.Join(helper.MapToSlice[string](metadata.Sizes, func(s string, size models.MetaDataFileSize) (r string, ok bool) {
|
|
||||||
up[2] = size.File
|
|
||||||
if s == "post-thumbnail" {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
r = fmt.Sprintf("%s/wp-content/uploads/%s %dw", host, strings.Join(up, "/"), size.Width)
|
|
||||||
ok = true
|
|
||||||
return
|
|
||||||
}), ", ")
|
|
||||||
r.Sizes = fmt.Sprintf("(max-width: %dpx) 100vw, %dpx", r.Width, r.Width)
|
|
||||||
if r.Width >= 740 && r.Width < 767 {
|
|
||||||
r.Sizes = "(max-width: 706px) 89vw, (max-width: 767px) 82vw, 740px"
|
|
||||||
} else if r.Width >= 767 {
|
|
||||||
r.Sizes = "(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func thumbnail(metadata models.WpAttachmentMetadata, thumbType, host string) (r models.PostThumbnail) {
|
||||||
|
if _, ok := metadata.Sizes[thumbType]; ok {
|
||||||
|
r.Path = fmt.Sprintf("%s/wp-content/uploads/%s", host, metadata.File)
|
||||||
|
r.Width = metadata.Sizes[thumbType].Width
|
||||||
|
r.Height = metadata.Sizes[thumbType].Height
|
||||||
|
up := strings.Split(metadata.File, "/")
|
||||||
|
r.Srcset = strings.Join(helper.MapToSlice[string](metadata.Sizes, func(s string, size models.MetaDataFileSize) (r string, ok bool) {
|
||||||
|
up[2] = size.File
|
||||||
|
if s == "post-thumbnail" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
r = fmt.Sprintf("%s/wp-content/uploads/%s %dw", host, strings.Join(up, "/"), size.Width)
|
||||||
|
ok = true
|
||||||
|
return
|
||||||
|
}), ", ")
|
||||||
|
r.Sizes = fmt.Sprintf("(max-width: %dpx) 100vw, %dpx", r.Width, r.Width)
|
||||||
|
if r.Width >= 740 && r.Width < 767 {
|
||||||
|
r.Sizes = "(max-width: 706px) 89vw, (max-width: 767px) 82vw, 740px"
|
||||||
|
} else if r.Width >= 767 {
|
||||||
|
r.Sizes = "(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
@ -52,13 +52,28 @@ func GetPostsByIds(ids ...any) (m map[uint64]models.Posts, err error) {
|
||||||
t = append(t, fmt.Sprintf(`<a href="/p/category/%s" rel="category tag">%s</a>`, cat, cat))
|
t = append(t, fmt.Sprintf(`<a href="/p/category/%s" rel="category tag">%s</a>`, cat, cat))
|
||||||
}
|
}
|
||||||
pp.CategoriesHtml = strings.Join(t, "、")
|
pp.CategoriesHtml = strings.Join(t, "、")
|
||||||
mm, ok := meta[pp.Id]
|
}
|
||||||
|
mm, ok := meta[pp.Id]
|
||||||
|
if ok {
|
||||||
|
attMeta, ok := mm["_wp_attachment_metadata"]
|
||||||
if ok {
|
if ok {
|
||||||
|
att, ok := attMeta.(models.WpAttachmentMetadata)
|
||||||
|
if ok {
|
||||||
|
pp.AttachmentMetadata = att
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if pp.PostType != "attachment" {
|
||||||
thumb := ToPostThumb(ctx, mm, host)
|
thumb := ToPostThumb(ctx, mm, host)
|
||||||
if thumb.Path != "" {
|
if thumb.Path != "" {
|
||||||
pp.Thumbnail = thumb
|
pp.Thumbnail = thumb
|
||||||
}
|
}
|
||||||
|
} else if pp.PostType == "attachment" && pp.AttachmentMetadata.File != "" {
|
||||||
|
thumb := thumbnail(pp.AttachmentMetadata, "thumbnail", host)
|
||||||
|
if thumb.Path != "" {
|
||||||
|
pp.Thumbnail = thumb
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if len(pp.Tags) > 0 {
|
if len(pp.Tags) > 0 {
|
||||||
t := make([]string, 0, len(pp.Tags))
|
t := make([]string, 0, len(pp.Tags))
|
||||||
|
|
|
@ -29,7 +29,7 @@ func (p Postmeta) AttachmentMetadata() (r WpAttachmentMetadata, err error) {
|
||||||
}
|
}
|
||||||
info, ok := unSerialize.(map[string]any)
|
info, ok := unSerialize.(map[string]any)
|
||||||
if ok {
|
if ok {
|
||||||
r, err = helper.MapToStruct[WpAttachmentMetadata](info)
|
r, err = helper.StrAnyMapToStruct[WpAttachmentMetadata](info)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
@ -42,7 +42,7 @@ func AttachmentMetadata(s string) (r WpAttachmentMetadata, err error) {
|
||||||
}
|
}
|
||||||
info, ok := unSerialize.(map[string]any)
|
info, ok := unSerialize.(map[string]any)
|
||||||
if ok {
|
if ok {
|
||||||
r, err = helper.MapToStruct[WpAttachmentMetadata](info)
|
r, err = helper.StrAnyMapToStruct[WpAttachmentMetadata](info)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,21 @@ const (
|
||||||
Category
|
Category
|
||||||
Search
|
Search
|
||||||
Detail
|
Detail
|
||||||
|
Empty404
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var IndexSceneMap = map[int]struct{}{
|
||||||
|
Home: {},
|
||||||
|
Archive: {},
|
||||||
|
Category: {},
|
||||||
|
Search: {},
|
||||||
|
}
|
||||||
|
|
||||||
|
var DetailSceneMap = map[int]struct{}{
|
||||||
|
Detail: {},
|
||||||
|
Empty404: {},
|
||||||
|
}
|
||||||
|
|
||||||
type Func[T any] func(*Plugin[T], *gin.Context, *T, uint)
|
type Func[T any] func(*Plugin[T], *gin.Context, *T, uint)
|
||||||
|
|
||||||
type Plugin[T any] struct {
|
type Plugin[T any] struct {
|
||||||
|
|
36
internal/templates/templateFuncs.go
Normal file
36
internal/templates/templateFuncs.go
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
package templates
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"github/fthvgb1/wp-go/internal/wpconfig"
|
||||||
|
"html/template"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var funcs = template.FuncMap{
|
||||||
|
"unescaped": func(s string) any {
|
||||||
|
return template.HTML(s)
|
||||||
|
},
|
||||||
|
"dateCh": func(t time.Time) any {
|
||||||
|
return t.Format("2006年 01月 02日")
|
||||||
|
},
|
||||||
|
"getOption": func(k string) string {
|
||||||
|
return wpconfig.Options.Value(k)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func FuncMap() template.FuncMap {
|
||||||
|
return funcs
|
||||||
|
}
|
||||||
|
|
||||||
|
func InitTemplateFunc() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func AddTemplateFunc(fnName string, fn any) error {
|
||||||
|
if _, ok := funcs[fnName]; ok {
|
||||||
|
return errors.New("a same name func exists")
|
||||||
|
}
|
||||||
|
funcs[fnName] = fn
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -15,18 +15,26 @@
|
||||||
|
|
||||||
<div class="custom-header" style="margin-bottom: 0px;">
|
<div class="custom-header" style="margin-bottom: 0px;">
|
||||||
<div class="custom-header-media">
|
<div class="custom-header-media">
|
||||||
<div id="wp-custom-header" class="wp-custom-header"><img src="/wp-content/themes/twentyseventeen/assets/images/header.jpg" width="2000" height="1200" alt=""></div> </div>
|
<div id="wp-custom-header" class="wp-custom-header">
|
||||||
|
<img src="{{.HeaderImage.Path}}" width="{{.HeaderImage.Width}}" height="{{.HeaderImage.Height}}" alt="" {{if .HeaderImage.Srcset}}srcset="{{.HeaderImage.Srcset}}" {{end}} {{if .HeaderImage.Sizes}}sizes="{{.HeaderImage.Srcset}}" {{end}}>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="site-branding" style="margin-bottom: 0px;">
|
<div class="site-branding" style="margin-bottom: 0px;">
|
||||||
<div class="wrap">
|
<div class="wrap">
|
||||||
<div class="site-branding-text">
|
<div class="site-branding-text">
|
||||||
<h1 class="site-title"><a href="/" rel="home">{{ "blogname"| getOption }}</a></h1>
|
<h1 class="site-title">
|
||||||
|
<a href="/" rel="home">{{ "blogname"| getOption }}</a>
|
||||||
|
</h1>
|
||||||
<p class="site-description">{{"blogdescription"| getOption}}</p>
|
<p class="site-description">{{"blogdescription"| getOption}}</p>
|
||||||
</div><!-- .site-branding-text -->
|
</div><!-- .site-branding-text -->
|
||||||
|
|
||||||
<a href="#content" class="menu-scroll-down"><svg class="icon icon-arrow-right" aria-hidden="true" role="img"> <use href="#icon-arrow-right" xlink:href="#icon-arrow-right"></use> </svg><span class="screen-reader-text">向下滚动到内容</span></a>
|
<a href="#content" class="menu-scroll-down">
|
||||||
|
<svg class="icon icon-arrow-right" aria-hidden="true" role="img">
|
||||||
|
<use href="#icon-arrow-right" xlink:href="#icon-arrow-right"></use>
|
||||||
|
</svg>
|
||||||
|
<span class="screen-reader-text">向下滚动到内容</span>
|
||||||
|
</a>
|
||||||
</div><!-- .wrap -->
|
</div><!-- .wrap -->
|
||||||
</div><!-- .site-branding -->
|
</div><!-- .site-branding -->
|
||||||
|
|
||||||
|
@ -51,7 +59,6 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{{template "layout/footer" .}}
|
{{template "layout/footer" .}}
|
||||||
</body>
|
</body>
|
||||||
|
|
74
internal/templates/twentyseventeen/theme.go
Normal file
74
internal/templates/twentyseventeen/theme.go
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
package twentyseventeen
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/elliotchance/phpserialize"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github/fthvgb1/wp-go/helper"
|
||||||
|
"github/fthvgb1/wp-go/internal/pkg/cache"
|
||||||
|
"github/fthvgb1/wp-go/internal/pkg/logs"
|
||||||
|
"github/fthvgb1/wp-go/internal/pkg/models"
|
||||||
|
"github/fthvgb1/wp-go/internal/plugins"
|
||||||
|
"github/fthvgb1/wp-go/internal/wpconfig"
|
||||||
|
)
|
||||||
|
|
||||||
|
const ThemeName = "twentyseventeen"
|
||||||
|
|
||||||
|
type HeaderImageMeta struct {
|
||||||
|
CustomCssPostId int `json:"custom_css_post_id,omitempty"`
|
||||||
|
NavMenuLocations []string `json:"nav_menu_locations,omitempty"`
|
||||||
|
HeaderImage string `json:"header_image,omitempty"`
|
||||||
|
HeaderImagData ImageData `json:"header_image_data,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ImageData struct {
|
||||||
|
AttachmentId int64 `json:"attachment_id,omitempty"`
|
||||||
|
Url string `json:"url,omitempty"`
|
||||||
|
ThumbnailUrl string `json:"thumbnail_url,omitempty"`
|
||||||
|
Height int64 `json:"height,omitempty"`
|
||||||
|
Width int64 `json:"width,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func Hook(c *gin.Context, h gin.H, scene int) (r string) {
|
||||||
|
if _, ok := plugins.IndexSceneMap[scene]; ok {
|
||||||
|
r = "twentyseventeen/posts/index.gohtml"
|
||||||
|
h["HeaderImage"] = getHeaderImage(c)
|
||||||
|
} else if _, ok := plugins.DetailSceneMap[scene]; ok {
|
||||||
|
r = "twentyseventeen/posts/detail.gohtml"
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func getHeaderImage(c *gin.Context) (r models.PostThumbnail) {
|
||||||
|
r.Path = "/wp-content/themes/twentyseventeen/assets/images/header.jpg"
|
||||||
|
r.Width = 2000
|
||||||
|
r.Height = 1200
|
||||||
|
meta, err := getHeaderMarkup()
|
||||||
|
if err != nil {
|
||||||
|
logs.ErrPrintln(err, "解析主题背景图设置错误")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if meta.HeaderImagData.AttachmentId > 0 {
|
||||||
|
m, err := cache.GetPostById(c, uint64(meta.HeaderImagData.AttachmentId))
|
||||||
|
if err != nil {
|
||||||
|
logs.ErrPrintln(err, "获取主题背景图信息错误")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if m.Thumbnail.Path != "" {
|
||||||
|
r = m.Thumbnail
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func getHeaderMarkup() (r HeaderImageMeta, err error) {
|
||||||
|
mods, ok := wpconfig.Options.Load("theme_mods_twentyseventeen")
|
||||||
|
var rr map[any]any
|
||||||
|
if ok {
|
||||||
|
err = phpserialize.Unmarshal([]byte(mods), &rr)
|
||||||
|
if err == nil {
|
||||||
|
rx := helper.MapAnyAnyToStrAny(rr)
|
||||||
|
r, err = helper.StrAnyMapToStruct[HeaderImageMeta](rx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user