twentyseventeen 主题 header 图
This commit is contained in:
parent
470312936c
commit
a748d53f5a
1
go.mod
1
go.mod
|
@ -16,6 +16,7 @@ require (
|
|||
)
|
||||
|
||||
require (
|
||||
github.com/elliotchance/phpserialize v1.3.3 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/go-playground/locales v0.14.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/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo=
|
||||
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/go.mod h1:QOJlmV2xmayAjkNS2Y8NQsMneuRShOU/kjovCXNuzzk=
|
||||
github.com/gin-contrib/pprof v1.4.0 h1:XxiBSf5jWZ5i16lNOPbMTVdgHBdhfGRD5PZ1LWazzvg=
|
||||
|
|
|
@ -2,7 +2,7 @@ package helper
|
|||
|
||||
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)
|
||||
if err != nil {
|
||||
return
|
||||
|
@ -11,12 +11,12 @@ func MapToStruct[T any, M any](m M) (r T, err error) {
|
|||
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)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
r = make(map[string]any)
|
||||
r = make(map[K]any)
|
||||
err = json.Unmarshal(marshal, &r)
|
||||
return
|
||||
}
|
||||
|
@ -31,16 +31,15 @@ func MapToSlice[T any, K comparable, V any](m map[K]V, fn func(K, V) (T, bool))
|
|||
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)
|
||||
for k, v := range m {
|
||||
kk, ok := k.(string)
|
||||
if ok {
|
||||
vv, ok := v.(map[any]any)
|
||||
if ok {
|
||||
x := make(map[string]any)
|
||||
MapAnyToString(vv)
|
||||
r[kk] = x
|
||||
r[kk] = MapAnyAnyToStrAny(vv)
|
||||
} else {
|
||||
r[kk] = v
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ type Me struct {
|
|||
Null any
|
||||
}
|
||||
|
||||
func TestMapToStruct(t *testing.T) {
|
||||
func TestStrAnyMapToStruct(t *testing.T) {
|
||||
type args struct {
|
||||
m map[string]any
|
||||
}
|
||||
|
@ -60,19 +60,19 @@ func TestMapToStruct(t *testing.T) {
|
|||
}
|
||||
for _, tt := range tests {
|
||||
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 {
|
||||
t.Errorf("MapToStruct() error = %v, wantErr %v", err, tt.wantErr)
|
||||
t.Errorf("StrAnyMapToStruct() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
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 {
|
||||
s T
|
||||
}
|
||||
|
@ -113,13 +113,13 @@ func TestStructToMap(t *testing.T) {
|
|||
}
|
||||
for _, tt := range tests {
|
||||
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 {
|
||||
t.Errorf("StructToMap() error = %v, wantErr %v", err, tt.wantErr)
|
||||
t.Errorf("StructToAnyMap() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
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-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"
|
||||
|
@ -202,7 +203,9 @@ func Index(c *gin.Context) {
|
|||
stat = http.StatusInternalServerError
|
||||
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()
|
||||
if err != nil {
|
||||
|
@ -224,6 +227,7 @@ func Index(c *gin.Context) {
|
|||
}
|
||||
if len(postIds) < 1 && h.category != "" {
|
||||
h.titleL = "未找到页面"
|
||||
h.scene = plugins.Empty404
|
||||
}
|
||||
|
||||
pw := h.session.Get("post_password")
|
||||
|
@ -247,6 +251,7 @@ func Index(c *gin.Context) {
|
|||
}
|
||||
ginH["posts"] = postIds
|
||||
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["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"
|
||||
"fmt"
|
||||
"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/mail"
|
||||
"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/logs"
|
||||
"github/fthvgb1/wp-go/internal/plugins"
|
||||
"github/fthvgb1/wp-go/internal/templates"
|
||||
"github/fthvgb1/wp-go/internal/wpconfig"
|
||||
"github/fthvgb1/wp-go/model"
|
||||
"log"
|
||||
|
@ -46,6 +48,8 @@ func init() {
|
|||
actions.InitFeed()
|
||||
cache.InitActionsCommonCache()
|
||||
plugins.InitDigestCache()
|
||||
templates.InitTemplateFunc()
|
||||
theme.InitTheme()
|
||||
go cronClearCache()
|
||||
}
|
||||
|
||||
|
|
|
@ -11,10 +11,7 @@ import (
|
|||
"github/fthvgb1/wp-go/internal/pkg/config"
|
||||
"github/fthvgb1/wp-go/internal/static"
|
||||
"github/fthvgb1/wp-go/internal/templates"
|
||||
"github/fthvgb1/wp-go/internal/wpconfig"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
func SetupRouter() (*gin.Engine, func()) {
|
||||
|
@ -29,17 +26,7 @@ func SetupRouter() (*gin.Engine, func()) {
|
|||
}
|
||||
}
|
||||
|
||||
r.HTMLRender = templates.NewFsTemplate(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)
|
||||
},
|
||||
}).SetTemplate()
|
||||
r.HTMLRender = templates.NewFsTemplate(templates.FuncMap()).SetTemplate()
|
||||
validServerName, reloadValidServerNameFn := middleware.ValidateServerNames()
|
||||
fl, flReload := middleware.FlowLimit(c.MaxRequestSleepNum, c.MaxRequestNum, c.SleepTime)
|
||||
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/dao"
|
||||
"github/fthvgb1/wp-go/internal/pkg/logs"
|
||||
models2 "github/fthvgb1/wp-go/internal/pkg/models"
|
||||
"github/fthvgb1/wp-go/internal/pkg/models"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var postContextCache *cache.MapCache[uint64, common.PostContext]
|
||||
var archivesCaches *Arch
|
||||
var categoryCaches *cache.SliceCache[models2.TermsMy]
|
||||
var recentPostsCaches *cache.SliceCache[models2.Posts]
|
||||
var recentCommentsCaches *cache.SliceCache[models2.Comments]
|
||||
var categoryCaches *cache.SliceCache[models.TermsMy]
|
||||
var recentPostsCaches *cache.SliceCache[models.Posts]
|
||||
var recentCommentsCaches *cache.SliceCache[models.Comments]
|
||||
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]
|
||||
|
||||
|
@ -26,9 +26,9 @@ var postListIdsCache *cache.MapCache[string, common.PostIds]
|
|||
var searchPostIdsCache *cache.MapCache[string, common.PostIds]
|
||||
var maxPostIdCache *cache.SliceCache[uint64]
|
||||
|
||||
var usersCache *cache.MapCache[uint64, models2.Users]
|
||||
var usersNameCache *cache.MapCache[string, models2.Users]
|
||||
var commentsCache *cache.MapCache[uint64, models2.Comments]
|
||||
var usersCache *cache.MapCache[uint64, models.Users]
|
||||
var usersNameCache *cache.MapCache[string, models.Users]
|
||||
var commentsCache *cache.MapCache[uint64, models.Comments]
|
||||
|
||||
func InitActionsCommonCache() {
|
||||
c := config.Conf.Load()
|
||||
|
@ -45,25 +45,25 @@ func InitActionsCommonCache() {
|
|||
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
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() {
|
||||
|
@ -89,18 +89,18 @@ func FlushCache() {
|
|||
usersCache.Flush()
|
||||
}
|
||||
|
||||
func Archives(ctx context.Context) (r []models2.PostArchive) {
|
||||
func Archives(ctx context.Context) (r []models.PostArchive) {
|
||||
return archivesCaches.getArchiveCache(ctx)
|
||||
}
|
||||
|
||||
type Arch struct {
|
||||
data []models2.PostArchive
|
||||
data []models.PostArchive
|
||||
mutex *sync.Mutex
|
||||
setCacheFunc func(context.Context) ([]models2.PostArchive, error)
|
||||
setCacheFunc func(context.Context) ([]models.PostArchive, error)
|
||||
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)
|
||||
m := time.Now().Month()
|
||||
if l > 0 && c.month != m || l < 1 {
|
||||
|
@ -117,7 +117,7 @@ func (c *Arch) getArchiveCache(ctx context.Context) []models2.PostArchive {
|
|||
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)
|
||||
logs.ErrPrintln(err, "get category ")
|
||||
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) {
|
||||
if meta != nil {
|
||||
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 {
|
||||
id, err := strconv.ParseUint(m.(string), 10, 64)
|
||||
if err == nil {
|
||||
mx, err := GetPostMetaByPostIds(c, []uint64{id})
|
||||
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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
metadata, ok := x.(models.WpAttachmentMetadata)
|
||||
if ok {
|
||||
r = thumbnail(metadata, "post-thumbnail", host)
|
||||
}
|
||||
}
|
||||
}
|
||||
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))
|
||||
}
|
||||
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 {
|
||||
att, ok := attMeta.(models.WpAttachmentMetadata)
|
||||
if ok {
|
||||
pp.AttachmentMetadata = att
|
||||
}
|
||||
}
|
||||
if pp.PostType != "attachment" {
|
||||
thumb := ToPostThumb(ctx, mm, host)
|
||||
if thumb.Path != "" {
|
||||
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 {
|
||||
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)
|
||||
if ok {
|
||||
r, err = helper.MapToStruct[WpAttachmentMetadata](info)
|
||||
r, err = helper.StrAnyMapToStruct[WpAttachmentMetadata](info)
|
||||
}
|
||||
}
|
||||
return
|
||||
|
@ -42,7 +42,7 @@ func AttachmentMetadata(s string) (r WpAttachmentMetadata, err error) {
|
|||
}
|
||||
info, ok := unSerialize.(map[string]any)
|
||||
if ok {
|
||||
r, err = helper.MapToStruct[WpAttachmentMetadata](info)
|
||||
r, err = helper.StrAnyMapToStruct[WpAttachmentMetadata](info)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
@ -10,8 +10,21 @@ const (
|
|||
Category
|
||||
Search
|
||||
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 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-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="wrap">
|
||||
<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>
|
||||
</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><!-- .site-branding -->
|
||||
|
||||
|
@ -51,7 +59,6 @@
|
|||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
{{template "layout/footer" .}}
|
||||
</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