diff --git a/go.mod b/go.mod index a19ca2f..dde91cd 100644 --- a/go.mod +++ b/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 diff --git a/go.sum b/go.sum index 1e07ec5..ae8787e 100644 --- a/go.sum +++ b/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= diff --git a/helper/map.go b/helper/map.go index fb26f7f..9f64c56 100644 --- a/helper/map.go +++ b/helper/map.go @@ -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 } diff --git a/helper/map_test.go b/helper/map_test.go index 2bb9edc..4084cc7 100644 --- a/helper/map_test.go +++ b/helper/map_test.go @@ -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) } }) } diff --git a/internal/actions/index.go b/internal/actions/index.go index d34c928..f9740f4 100644 --- a/internal/actions/index.go +++ b/internal/actions/index.go @@ -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() } diff --git a/internal/actions/theme/theme.go b/internal/actions/theme/theme.go new file mode 100644 index 0000000..267e951 --- /dev/null +++ b/internal/actions/theme/theme.go @@ -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" +} diff --git a/internal/cmd/main.go b/internal/cmd/main.go index 78e3302..2d23b02 100644 --- a/internal/cmd/main.go +++ b/internal/cmd/main.go @@ -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() } diff --git a/internal/cmd/route/route.go b/internal/cmd/route/route.go index ab23c64..25ad503 100644 --- a/internal/cmd/route/route.go +++ b/internal/cmd/route/route.go @@ -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( diff --git a/internal/pkg/cache/cache.go b/internal/pkg/cache/cache.go index d2d775f..090ec3a 100644 --- a/internal/pkg/cache/cache.go +++ b/internal/pkg/cache/cache.go @@ -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 diff --git a/internal/pkg/dao/postmeta.go b/internal/pkg/dao/postmeta.go index 8c5b173..8fefefd 100644 --- a/internal/pkg/dao/postmeta.go +++ b/internal/pkg/dao/postmeta.go @@ -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 +} diff --git a/internal/pkg/dao/posts.go b/internal/pkg/dao/posts.go index 9ca7d90..aabc8da 100644 --- a/internal/pkg/dao/posts.go +++ b/internal/pkg/dao/posts.go @@ -52,13 +52,28 @@ func GetPostsByIds(ids ...any) (m map[uint64]models.Posts, err error) { t = append(t, fmt.Sprintf(`%s`, 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)) diff --git a/internal/pkg/models/wp_postmeta.go b/internal/pkg/models/wp_postmeta.go index e2fcfdf..c4ef3aa 100644 --- a/internal/pkg/models/wp_postmeta.go +++ b/internal/pkg/models/wp_postmeta.go @@ -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 } diff --git a/internal/plugins/plugins.go b/internal/plugins/plugins.go index 30a7aff..bda3fea 100644 --- a/internal/plugins/plugins.go +++ b/internal/plugins/plugins.go @@ -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 { diff --git a/internal/templates/templateFuncs.go b/internal/templates/templateFuncs.go new file mode 100644 index 0000000..3c941a2 --- /dev/null +++ b/internal/templates/templateFuncs.go @@ -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 +} diff --git a/internal/templates/twentyseventeen/layout/base.gohtml b/internal/templates/twentyseventeen/layout/base.gohtml index fe94ee1..6da1c53 100644 --- a/internal/templates/twentyseventeen/layout/base.gohtml +++ b/internal/templates/twentyseventeen/layout/base.gohtml @@ -15,18 +15,26 @@
-
+
+ +
+
-

{{ "blogname"| getOption }}

- +

+ {{ "blogname"| getOption }} +

{{"blogdescription"| getOption}}

- 向下滚动到内容 - + + + 向下滚动到内容 +
@@ -51,7 +59,6 @@ - {{template "layout/footer" .}} diff --git a/internal/templates/twentyseventeen/theme.go b/internal/templates/twentyseventeen/theme.go new file mode 100644 index 0000000..9a95de0 --- /dev/null +++ b/internal/templates/twentyseventeen/theme.go @@ -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 +}