twentyseventeen 主题 header 图

This commit is contained in:
xing 2023-01-17 23:18:31 +08:00
parent 470312936c
commit a748d53f5a
16 changed files with 276 additions and 100 deletions

1
go.mod
View File

@ -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
View File

@ -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=

View File

@ -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
}

View File

@ -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)
}
})
}

View File

@ -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()
}

View 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"
}

View File

@ -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()
}

View File

@ -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(

View File

@ -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

View File

@ -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
}

View File

@ -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))

View File

@ -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
}

View File

@ -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 {

View 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
}

View File

@ -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>

View 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
}