diff --git a/helper/func.go b/helper/func.go
index ff53435..695c1b8 100644
--- a/helper/func.go
+++ b/helper/func.go
@@ -1,7 +1,9 @@
package helper
import (
+ "net/url"
"reflect"
+ "strings"
)
func ToAny[T any](v T) any {
@@ -24,3 +26,35 @@ func StructColumnToSlice[T any, M any](arr []M, field string) (r []T) {
}
return
}
+
+func UrlScheme(u string, isHttps bool) string {
+ return Or(isHttps,
+ strings.Replace(u, "http://", "https://", 1),
+ strings.Replace(u, "https://", "http://", 1),
+ )
+}
+
+func CutUrlHost(u string) string {
+ ur, err := url.Parse(u)
+ if err != nil {
+ return u
+ }
+ ur.Scheme = ""
+ ur.Host = ""
+ return ur.String()
+}
+
+func Defaults[T comparable](v, defaults T) T {
+ var zero T
+ if v == zero {
+ return defaults
+ }
+ return v
+}
+func DefaultVal[T any](v, defaults T) T {
+ var zero T
+ if reflect.DeepEqual(zero, v) {
+ return defaults
+ }
+ return v
+}
diff --git a/helper/func_test.go b/helper/func_test.go
index 7ea6f0c..26e8363 100644
--- a/helper/func_test.go
+++ b/helper/func_test.go
@@ -97,3 +97,50 @@ func TestToAny(t *testing.T) {
})
}
}
+
+func TestCutUrlHost(t *testing.T) {
+ type args struct {
+ u string
+ }
+ tests := []struct {
+ name string
+ args args
+ want string
+ }{
+ {
+ name: "http",
+ args: args{"http://xx.yy/xxoo?ss=fff"},
+ want: "/xxoo?ss=fff",
+ }, {
+ name: "https",
+ args: args{"https://xx.yy/xxoo?ff=fff"},
+ want: "/xxoo?ff=fff",
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ if got := CutUrlHost(tt.args.u); got != tt.want {
+ t.Errorf("CutUrlHost() = %v, want %v", got, tt.want)
+ }
+ })
+ }
+}
+
+func TestDefaults(t *testing.T) {
+ v := 0
+ want := 1
+ t.Run("int", func(t *testing.T) {
+ if got := Defaults(v, want); !reflect.DeepEqual(got, want) {
+ t.Errorf("Defaults() = %v, want %v", got, want)
+ }
+ })
+ {
+ v := ""
+ want := "a"
+ t.Run("string", func(t *testing.T) {
+ if got := Defaults(v, want); !reflect.DeepEqual(got, want) {
+ t.Errorf("Defaults() = %v, want %v", got, want)
+ }
+ })
+ }
+}
diff --git a/helper/maps/map.go b/helper/maps/map.go
index bd4e8f6..b9d7dd8 100644
--- a/helper/maps/map.go
+++ b/helper/maps/map.go
@@ -108,3 +108,11 @@ func Merge[K comparable, V any](m ...map[K]V) map[K]V {
}
return mm
}
+
+func WithDefaultVal[K comparable, V any](m map[K]V, k K, defaults V) V {
+ vv, ok := m[k]
+ if ok {
+ return vv
+ }
+ return defaults
+}
diff --git a/internal/cmd/main.go b/internal/cmd/main.go
index 1be0851..3f1f339 100644
--- a/internal/cmd/main.go
+++ b/internal/cmd/main.go
@@ -11,6 +11,7 @@ import (
"github.com/fthvgb1/wp-go/internal/pkg/logs"
"github.com/fthvgb1/wp-go/internal/plugins"
"github.com/fthvgb1/wp-go/internal/theme"
+ "github.com/fthvgb1/wp-go/internal/theme/common"
"github.com/fthvgb1/wp-go/internal/wpconfig"
"github.com/fthvgb1/wp-go/model"
"log"
@@ -106,6 +107,7 @@ func reload() {
logs.ErrPrintln(err, "获取网站设置WpOption失败")
err = wpconfig.InitTerms()
wpconfig.FlushModes()
+ common.Reload()
logs.ErrPrintln(err, "获取WpTerms表失败")
if middleWareReloadFn != nil {
middleWareReloadFn()
diff --git a/internal/cmd/route/route.go b/internal/cmd/route/route.go
index e9dab53..e4360f0 100644
--- a/internal/cmd/route/route.go
+++ b/internal/cmd/route/route.go
@@ -7,6 +7,7 @@ import (
"github.com/fthvgb1/wp-go/internal/pkg/constraints"
"github.com/fthvgb1/wp-go/internal/static"
"github.com/fthvgb1/wp-go/internal/theme"
+ "github.com/fthvgb1/wp-go/internal/wpconfig"
"github.com/gin-contrib/gzip"
"github.com/gin-contrib/pprof"
"github.com/gin-contrib/sessions"
@@ -28,6 +29,7 @@ func SetupRouter() (*gin.Engine, func()) {
}
r.HTMLRender = theme.GetTemplate()
+ wpconfig.SetTemplateFs(theme.TemplateFs)
validServerName, reloadValidServerNameFn := middleware.ValidateServerNames()
fl, flReload := middleware.FlowLimit(c.MaxRequestSleepNum, c.MaxRequestNum, c.CacheTime.SleepTime)
diff --git a/internal/theme/common/custombackground.go b/internal/theme/common/custombackground.go
new file mode 100644
index 0000000..9b9a1d2
--- /dev/null
+++ b/internal/theme/common/custombackground.go
@@ -0,0 +1,85 @@
+package common
+
+import (
+ "fmt"
+ "github.com/fthvgb1/wp-go/helper"
+ "github.com/fthvgb1/wp-go/helper/maps"
+ "github.com/fthvgb1/wp-go/internal/wpconfig"
+ "github.com/fthvgb1/wp-go/safety"
+ "strings"
+)
+
+var postx = map[string]string{
+ "left": "left",
+ "right": "right",
+ "center": "center",
+}
+var posty = map[string]string{
+ "top": "top",
+ "bottom": "bottom",
+ "center": "center",
+}
+var size = map[string]string{
+ "auto": "auto",
+ "contain": "contain",
+ "cover": "cover",
+}
+var repeat = map[string]string{
+ "repeat-x": "repeat-x",
+ "repeat-y": "repeat-y",
+ "repeat": "repeat",
+ "no-repeat": "no-repeat",
+}
+
+var backgroud = safety.NewVar("")
+
+func (h *Handle) CustomBackGround() {
+ b := backgroud.Load()
+ if b == "" {
+ b = h.CalCustomBackGround()
+ backgroud.Store(b)
+ }
+ h.GinH["customBackground"] = b
+}
+
+func (h *Handle) CalCustomBackGround() (r string) {
+ mods, err := wpconfig.GetThemeMods(h.Theme)
+ if err != nil {
+ return
+ }
+ if mods.BackgroundImage == "" && mods.BackgroundColor == mods.ThemeSupport.CustomBackground.DefaultColor {
+ return
+ }
+ s := strings.Builder{}
+ if mods.BackgroundImage != "" {
+ s.WriteString(` background-image: url("`)
+ s.WriteString(helper.CutUrlHost(mods.BackgroundImage))
+ s.WriteString(`");`)
+ }
+ backgroundPositionX := helper.Defaults(mods.BackgroundPositionX, mods.ThemeSupport.CustomBackground.DefaultPositionX)
+ backgroundPositionX = maps.WithDefaultVal(postx, backgroundPositionX, "left")
+
+ backgroundPositionY := helper.Defaults(mods.BackgroundPositionY, mods.ThemeSupport.CustomBackground.DefaultPositionY)
+ backgroundPositionY = maps.WithDefaultVal(posty, backgroundPositionY, "top")
+ positon := fmt.Sprintf(" background-position: %s %s;", backgroundPositionX, backgroundPositionY)
+
+ siz := helper.DefaultVal(mods.BackgroundSize, mods.ThemeSupport.CustomBackground.DefaultSize)
+ siz = maps.WithDefaultVal(size, siz, "auto")
+ siz = fmt.Sprintf(" background-size: %s;", siz)
+
+ repeats := helper.Defaults(mods.BackgroundRepeat, mods.ThemeSupport.CustomBackground.DefaultRepeat)
+ repeats = maps.WithDefaultVal(repeat, repeats, "repeat")
+ repeats = fmt.Sprintf(" background-repeat: %s;", repeats)
+
+ attachment := helper.Defaults(mods.BackgroundAttachment, mods.ThemeSupport.CustomBackground.DefaultAttachment)
+ attachment = helper.Or(attachment == "fixed", "fixed", "scroll")
+ attachment = fmt.Sprintf(" background-attachment: %s;", attachment)
+ s.WriteString(positon)
+ s.WriteString(siz)
+ s.WriteString(repeats)
+ s.WriteString(attachment)
+ r = fmt.Sprintf(``, s.String())
+ return
+}
diff --git a/internal/theme/common/detail.go b/internal/theme/common/detail.go
index 73f3710..4bc34e0 100644
--- a/internal/theme/common/detail.go
+++ b/internal/theme/common/detail.go
@@ -102,6 +102,7 @@ func (d *DetailHandle) Render() {
if d.Templ == "" {
d.Templ = fmt.Sprintf("%s/posts/detail.gohtml", d.Theme)
}
+ d.CustomBackGround()
d.C.HTML(d.Code, d.Templ, d.GinH)
}
diff --git a/internal/theme/common/index.go b/internal/theme/common/index.go
index 43e4a47..49a0475 100644
--- a/internal/theme/common/index.go
+++ b/internal/theme/common/index.go
@@ -116,6 +116,7 @@ func (i *IndexHandle) Render() {
if i.Templ == "" {
i.Templ = fmt.Sprintf("%s/posts/index.gohtml", i.Theme)
}
+ i.CustomBackGround()
i.C.HTML(i.Code, i.Templ, i.GinH)
}
diff --git a/internal/theme/common/reload.go b/internal/theme/common/reload.go
new file mode 100644
index 0000000..ea008b4
--- /dev/null
+++ b/internal/theme/common/reload.go
@@ -0,0 +1,5 @@
+package common
+
+func Reload() {
+ backgroud.Flush()
+}
diff --git a/internal/theme/twentyfifteen/colorscheme.json b/internal/theme/twentyfifteen/colorscheme.json
new file mode 100644
index 0000000..2720d14
--- /dev/null
+++ b/internal/theme/twentyfifteen/colorscheme.json
@@ -0,0 +1,68 @@
+{
+ "default": {
+ "label": "Default",
+ "colors": [
+ "#f1f1f1",
+ "#ffffff",
+ "#ffffff",
+ "#333333",
+ "#333333",
+ "#f7f7f7"
+ ]
+ },
+ "dark": {
+ "label": "Dark",
+ "colors": [
+ "#111111",
+ "#202020",
+ "#202020",
+ "#bebebe",
+ "#bebebe",
+ "#1b1b1b"
+ ]
+ },
+ "yellow": {
+ "label": "Yellow",
+ "colors": [
+ "#f4ca16",
+ "#ffdf00",
+ "#ffffff",
+ "#111111",
+ "#111111",
+ "#f1f1f1"
+ ]
+ },
+ "pink": {
+ "label": "Pink",
+ "colors": [
+ "#ffe5d1",
+ "#e53b51",
+ "#ffffff",
+ "#352712",
+ "#ffffff",
+ "#f1f1f1"
+ ]
+ },
+ "purple": {
+ "label": "Purple",
+ "colors": [
+ "#674970",
+ "#2e2256",
+ "#ffffff",
+ "#2e2256",
+ "#ffffff",
+ "#f1f1f1"
+ ]
+ },
+ "blue": {
+ "label": "Blue",
+ "colors": [
+ "#e9f2f9",
+ "#55c3dc",
+ "#ffffff",
+ "#22313f",
+ "#ffffff",
+ "#f1f1f1"
+ ]
+ }
+}
diff --git a/internal/theme/twentyfifteen/layout/head.gohtml b/internal/theme/twentyfifteen/layout/head.gohtml
index f6f3309..0b1bcdc 100644
--- a/internal/theme/twentyfifteen/layout/head.gohtml
+++ b/internal/theme/twentyfifteen/layout/head.gohtml
@@ -57,4 +57,8 @@
+
+ {{if .customBackground}}
+ {{.customBackground|unescaped}}
+ {{end}}
{{end}}
\ No newline at end of file
diff --git a/internal/theme/twentyfifteen/themesupport.json b/internal/theme/twentyfifteen/themesupport.json
new file mode 100644
index 0000000..dd285bb
--- /dev/null
+++ b/internal/theme/twentyfifteen/themesupport.json
@@ -0,0 +1,196 @@
+{
+ "core-block-patterns": true,
+ "widgets-block-editor": true,
+ "automatic-feed-links": true,
+ "title-tag": true,
+ "post-thumbnails": true,
+ "menus": true,
+ "html5": [
+ "search-form",
+ "comment-form",
+ "comment-list",
+ "gallery",
+ "caption",
+ "script",
+ "style",
+ "navigation-widgets"
+ ],
+ "post-formats": [
+ "aside",
+ "image",
+ "video",
+ "quote",
+ "link",
+ "gallery",
+ "status",
+ "audio",
+ "chat"
+ ],
+ "custom-logo": {
+ "width": 248,
+ "height": 248,
+ "flex-width": false,
+ "flex-height": true,
+ "header-text": "",
+ "unlink-homepage-logo": false
+ },
+ "custom-background": {
+ "default-image": "",
+ "default-preset": "default",
+ "default-position-x": "left",
+ "default-position-y": "top",
+ "default-size": "auto",
+ "default-repeat": "repeat",
+ "default-attachment": "fixed",
+ "default-color": "f1f1f1",
+ "wp-head-callback": "_custom_background_cb",
+ "admin-head-callback": "",
+ "admin-preview-callback": ""
+ },
+ "editor-style": true,
+ "editor-styles": true,
+ "wp-block-styles": true,
+ "responsive-embeds": true,
+ "editor-color-palette": [
+ {
+ "name": "暗灰色",
+ "slug": "dark-gray",
+ "color": "#111"
+ },
+ {
+ "name": "亮灰色",
+ "slug": "light-gray",
+ "color": "#f1f1f1"
+ },
+ {
+ "name": "白色",
+ "slug": "white",
+ "color": "#fff"
+ },
+ {
+ "name": "黄色",
+ "slug": "yellow",
+ "color": "#f4ca16"
+ },
+ {
+ "name": "暗棕色",
+ "slug": "dark-brown",
+ "color": "#352712"
+ },
+ {
+ "name": "粉色",
+ "slug": "medium-pink",
+ "color": "#e53b51"
+ },
+ {
+ "name": "浅粉色",
+ "slug": "light-pink",
+ "color": "#ffe5d1"
+ },
+ {
+ "name": "暗紫色",
+ "slug": "dark-purple",
+ "color": "#2e2256"
+ },
+ {
+ "name": "紫色",
+ "slug": "purple",
+ "color": "#674970"
+ },
+ {
+ "name": "蓝灰色",
+ "slug": "blue-gray",
+ "color": "#22313f"
+ },
+ {
+ "name": "亮蓝色",
+ "slug": "bright-blue",
+ "color": "#55c3dc"
+ },
+ {
+ "name": "浅蓝色",
+ "slug": "light-blue",
+ "color": "#e9f2f9"
+ }
+ ],
+ "editor-gradient-presets": [
+ {
+ "name": "Dark Gray Gradient",
+ "slug": "dark-gray-gradient-gradient",
+ "gradient": "linear-gradient(90deg, rgba(17,17,17,1) 0%, rgba(42,42,42,1) 100%)"
+ },
+ {
+ "name": "Light Gray Gradient",
+ "slug": "light-gray-gradient",
+ "gradient": "linear-gradient(90deg, rgba(241,241,241,1) 0%, rgba(215,215,215,1) 100%)"
+ },
+ {
+ "name": "White Gradient",
+ "slug": "white-gradient",
+ "gradient": "linear-gradient(90deg, rgba(255,255,255,1) 0%, rgba(230,230,230,1) 100%)"
+ },
+ {
+ "name": "Yellow Gradient",
+ "slug": "yellow-gradient",
+ "gradient": "linear-gradient(90deg, rgba(244,202,22,1) 0%, rgba(205,168,10,1) 100%)"
+ },
+ {
+ "name": "Dark Brown Gradient",
+ "slug": "dark-brown-gradient",
+ "gradient": "linear-gradient(90deg, rgba(53,39,18,1) 0%, rgba(91,67,31,1) 100%)"
+ },
+ {
+ "name": "Medium Pink Gradient",
+ "slug": "medium-pink-gradient",
+ "gradient": "linear-gradient(90deg, rgba(229,59,81,1) 0%, rgba(209,28,51,1) 100%)"
+ },
+ {
+ "name": "Light Pink Gradient",
+ "slug": "light-pink-gradient",
+ "gradient": "linear-gradient(90deg, rgba(255,229,209,1) 0%, rgba(255,200,158,1) 100%)"
+ },
+ {
+ "name": "Dark Purple Gradient",
+ "slug": "dark-purple-gradient",
+ "gradient": "linear-gradient(90deg, rgba(46,34,86,1) 0%, rgba(66,48,123,1) 100%)"
+ },
+ {
+ "name": "Purple Gradient",
+ "slug": "purple-gradient",
+ "gradient": "linear-gradient(90deg, rgba(103,73,112,1) 0%, rgba(131,93,143,1) 100%)"
+ },
+ {
+ "name": "Blue Gray Gradient",
+ "slug": "blue-gray-gradient",
+ "gradient": "linear-gradient(90deg, rgba(34,49,63,1) 0%, rgba(52,75,96,1) 100%)"
+ },
+ {
+ "name": "Bright Blue Gradient",
+ "slug": "bright-blue-gradient",
+ "gradient": "linear-gradient(90deg, rgba(85,195,220,1) 0%, rgba(43,180,211,1) 100%)"
+ },
+ {
+ "name": "Light Blue Gradient",
+ "slug": "light-blue-gradient",
+ "gradient": "linear-gradient(90deg, rgba(233,242,249,1) 0%, rgba(193,218,238,1) 100%)"
+ }
+ ],
+ "customize-selective-refresh-widgets": true,
+ "custom-header": {
+ "default-image": "",
+ "random-default": false,
+ "width": 954,
+ "height": 1300,
+ "flex-height": false,
+ "flex-width": false,
+ "default-text-color": "333333",
+ "header-text": true,
+ "uploads": true,
+ "wp-head-callback": "twentyfifteen_header_style",
+ "admin-head-callback": "",
+ "admin-preview-callback": "",
+ "video": false,
+ "video-active-callback": "is_front_page"
+ },
+ "widgets": true
+}
diff --git a/internal/theme/twentyseventeen/twentyseventeen.go b/internal/theme/twentyseventeen/twentyseventeen.go
index 579070e..c266911 100644
--- a/internal/theme/twentyseventeen/twentyseventeen.go
+++ b/internal/theme/twentyseventeen/twentyseventeen.go
@@ -195,3 +195,12 @@ var class = map[int]string{
constraints.Search: "search ",
constraints.Detail: "post-template-default single single-post single-format-standard ",
}
+
+func ThemeSupport() map[string]struct{} {
+ return map[string]struct{}{
+ "custom-header": {},
+ "wp-custom-logo": {},
+ "responsive-embeds": {},
+ "post-formats": {},
+ }
+}
diff --git a/internal/wpconfig/thememods.go b/internal/wpconfig/thememods.go
index 5359f1d..582e6b9 100644
--- a/internal/wpconfig/thememods.go
+++ b/internal/wpconfig/thememods.go
@@ -1,34 +1,53 @@
package wpconfig
import (
+ "embed"
+ "encoding/json"
"fmt"
"github.com/fthvgb1/wp-go/helper/maps"
"github.com/fthvgb1/wp-go/internal/phphelper"
"github.com/fthvgb1/wp-go/internal/pkg/models"
"github.com/fthvgb1/wp-go/safety"
+ "path/filepath"
"strings"
)
+var templateFs embed.FS
+
+func SetTemplateFs(fs embed.FS) {
+ templateFs = fs
+}
+
type ThemeMods struct {
- CustomCssPostId int `json:"custom_css_post_id,omitempty"`
- NavMenuLocations []string `json:"nav_menu_locations,omitempty"`
- CustomLogo int `json:"custom_logo"`
- HeaderImage string `json:"header_image,omitempty"`
- BackgroundImage string `json:"background_image"`
- BackgroundSize string `json:"background_size"`
- BackgroundRepeat string `json:"background_repeat"`
- BackgroundColor string `json:"background_color"`
- ColorScheme string `json:"color_scheme"`
- SidebarTextcolor string `json:"sidebar_textcolor"`
- HeaderBackgroundColor string `json:"header_background_color"`
- HeaderTextcolor string `json:"header_textcolor"`
+ CustomCssPostId int `json:"custom_css_post_id,omitempty"`
+ NavMenuLocations []string `json:"nav_menu_locations,omitempty"`
+ CustomLogo int `json:"custom_logo,omitempty"`
+ HeaderImage string `json:"header_image,omitempty"`
+ BackgroundImage string `json:"background_image,omitempty"`
+ BackgroundSize string `json:"background_size,omitempty"`
+ BackgroundRepeat string `json:"background_repeat,omitempty"`
+ BackgroundColor string `json:"background_color,omitempty"`
+ BackgroundPreset string `json:"background_preset"`
+ BackgroundPositionX string `json:"background_position_x,omitempty"`
+ BackgroundPositionY string `json:"background_position_y"`
+ BackgroundAttachment string `json:"background_attachment"`
+ ColorScheme map[string]ColorScheme
+ SidebarTextcolor string `json:"sidebar_textcolor,omitempty"`
+ HeaderBackgroundColor string `json:"header_background_color,omitempty"`
+ HeaderTextcolor string `json:"header_textcolor,omitempty"`
HeaderImagData ImageData `json:"header_image_data,omitempty"`
- SidebarsWidgets Sidebars `json:"sidebars_widgets"`
+ SidebarsWidgets Sidebars `json:"sidebars_widgets,omitempty"`
+ ThemeSupport ThemeSupport
}
type Sidebars struct {
Time int `json:"time,omitempty"`
- Data SidebarsData `json:"data"`
+ Data SidebarsData `json:"data,omitempty"`
+}
+
+type ColorScheme struct {
+ Label string `json:"label,omitempty"`
+ Colors []string `json:"colors,omitempty"`
}
type SidebarsData struct {
@@ -94,6 +113,7 @@ func GetThemeMods(theme string) (r ThemeMods, err error) {
if err != nil {
return
}
+ r.setThemeColorScheme(theme)
themeModes.Store(theme, r)
return
}
@@ -120,3 +140,28 @@ func IsCustomLogo(theme string) bool {
return false
}
+
+func (m *ThemeMods) setThemeColorScheme(themeName string) {
+ bytes, err := templateFs.ReadFile(filepath.Join(themeName, "colorscheme.json"))
+ if err != nil {
+ return
+ }
+ var scheme map[string]ColorScheme
+ err = json.Unmarshal(bytes, &scheme)
+ if err != nil {
+ return
+ }
+ m.ColorScheme = scheme
+}
+func (m *ThemeMods) setThemeSupport(themeName string) {
+ bytes, err := templateFs.ReadFile(filepath.Join(themeName, "themesupport.json"))
+ if err != nil {
+ return
+ }
+ var themeSupport ThemeSupport
+ err = json.Unmarshal(bytes, &themeSupport)
+ if err != nil {
+ return
+ }
+ m.ThemeSupport = themeSupport
+}
diff --git a/internal/wpconfig/themesupport.go b/internal/wpconfig/themesupport.go
new file mode 100644
index 0000000..070d7f2
--- /dev/null
+++ b/internal/wpconfig/themesupport.go
@@ -0,0 +1,70 @@
+package wpconfig
+
+type ThemeSupport struct {
+ CoreBlockPatterns bool `json:"core-block-patterns"`
+ WidgetsBlockEditor bool `json:"widgets-block-editor"`
+ AutomaticFeedLinks bool `json:"automatic-feed-links"`
+ TitleTag bool `json:"title-tag"`
+ PostThumbnails bool `json:"post-thumbnails"`
+ Menus bool `json:"menus"`
+ HTML5 []string `json:"html5"`
+ PostFormats []string `json:"post-formats"`
+ CustomLogo CustomLogo `json:"custom-logo"`
+ CustomBackground CustomBackground `json:"custom-background"`
+ EditorStyle bool `json:"editor-style"`
+ EditorStyles bool `json:"editor-styles"`
+ WpBlockStyles bool `json:"wp-block-styles"`
+ ResponsiveEmbeds bool `json:"responsive-embeds"`
+ EditorColorPalette []EditorColorPalette `json:"editor-color-palette"`
+ EditorGradientPresets []EditorGradientPresets `json:"editor-gradient-presets"`
+ CustomizeSelectiveRefreshWidgets bool `json:"customize-selective-refresh-widgets"`
+ CustomHeader CustomHeader `json:"custom-header"`
+ Widgets bool `json:"widgets"`
+}
+type CustomLogo struct {
+ Width int `json:"width"`
+ Height int `json:"height"`
+ FlexWidth bool `json:"flex-width"`
+ FlexHeight bool `json:"flex-height"`
+ HeaderText string `json:"header-text"`
+ UnlinkHomepageLogo bool `json:"unlink-homepage-logo"`
+}
+type CustomBackground struct {
+ DefaultImage string `json:"default-image"`
+ DefaultPreset string `json:"default-preset"`
+ DefaultPositionX string `json:"default-position-x"`
+ DefaultPositionY string `json:"default-position-y"`
+ DefaultSize string `json:"default-size"`
+ DefaultRepeat string `json:"default-repeat"`
+ DefaultAttachment string `json:"default-attachment"`
+ DefaultColor string `json:"default-color"`
+ WpHeadCallback string `json:"wp-head-callback"`
+ AdminHeadCallback string `json:"admin-head-callback"`
+ AdminPreviewCallback string `json:"admin-preview-callback"`
+}
+type EditorColorPalette struct {
+ Name string `json:"name"`
+ Slug string `json:"slug"`
+ Color string `json:"color"`
+}
+type EditorGradientPresets struct {
+ Name string `json:"name"`
+ Slug string `json:"slug"`
+ Gradient string `json:"gradient"`
+}
+type CustomHeader struct {
+ DefaultImage string `json:"default-image"`
+ RandomDefault bool `json:"random-default"`
+ Width int `json:"width"`
+ Height int `json:"height"`
+ FlexHeight bool `json:"flex-height"`
+ FlexWidth bool `json:"flex-width"`
+ DefaultTextColor string `json:"default-text-color"`
+ HeaderText bool `json:"header-text"`
+ Uploads bool `json:"uploads"`
+ WpHeadCallback string `json:"wp-head-callback"`
+ AdminHeadCallback string `json:"admin-head-callback"`
+ AdminPreviewCallback string `json:"admin-preview-callback"`
+ Video bool `json:"video"`
+ VideoActiveCallback string `json:"video-active-callback"`
+}
diff --git a/safety/vars.go b/safety/vars.go
index 6ac25af..87e5b9d 100644
--- a/safety/vars.go
+++ b/safety/vars.go
@@ -35,3 +35,13 @@ func (r *Var[T]) Store(v T) {
}
}
}
+
+func (r *Var[T]) Flush() {
+ for {
+ px := atomic.LoadPointer(&r.p)
+ var v T
+ if atomic.CompareAndSwapPointer(&r.p, px, unsafe.Pointer(&v)) {
+ return
+ }
+ }
+}
diff --git a/safety/vars_test.go b/safety/vars_test.go
index ed2f4d9..f2dc25b 100644
--- a/safety/vars_test.go
+++ b/safety/vars_test.go
@@ -1,6 +1,7 @@
package safety
import (
+ "fmt"
"reflect"
"testing"
"unsafe"
@@ -39,3 +40,27 @@ func TestVar_Load(t *testing.T) {
})
}
}
+
+func TestVar_Delete(t *testing.T) {
+ {
+ v := NewVar("")
+ t.Run("string", func(t *testing.T) {
+ v.Delete()
+ fmt.Println(v.Load())
+ v.Store("xx")
+ fmt.Println(v.Load())
+ })
+ }
+}
+
+func TestVar_Flush(t *testing.T) {
+ {
+ v := NewVar("")
+ t.Run("string", func(t *testing.T) {
+ v.Flush()
+ fmt.Println(v.Load())
+ v.Store("xx")
+ fmt.Println(v.Load())
+ })
+ }
+}