Compare commits

...

3 Commits

Author SHA1 Message Date
bebe6bac81 完善 2023-03-27 22:03:01 +08:00
a1f36da904 block版 分类 2023-03-27 12:59:29 +08:00
6f800230b0 优化 完善 2023-03-27 11:37:24 +08:00
24 changed files with 1056 additions and 354 deletions

View File

@ -96,6 +96,13 @@ func ToBool[T comparable](t T) bool {
return vv != t return vv != t
} }
func ToBoolInt(t any) int8 {
if IsZeros(t) {
return 0
}
return 1
}
func GetContextVal[V, K any](ctx context.Context, k K, defaults V) V { func GetContextVal[V, K any](ctx context.Context, k K, defaults V) V {
v := ctx.Value(k) v := ctx.Value(k)
if v == nil { if v == nil {

View File

@ -51,6 +51,19 @@ func AnyAnyToStrAny(m map[any]any) (r map[string]any) {
} }
return return
} }
func StrAnyToAnyAny(m map[string]any) (r map[any]any) {
r = make(map[any]any)
for kk, v := range m {
vv, ok := v.(map[string]any)
if ok {
r[kk] = StrAnyToAnyAny(vv)
} else {
r[kk] = v
}
}
return
}
func IsExists[K comparable, V any](m map[K]V, k K) bool { func IsExists[K comparable, V any](m map[K]V, k K) bool {
_, ok := m[k] _, ok := m[k]
@ -135,3 +148,14 @@ func WithDefaultVal[K comparable, V any](m map[K]V, k K, defaults V) V {
} }
return defaults return defaults
} }
func AnyAnyMap[K comparable, V any](m map[any]any, fn func(k, v any) (K, V, bool)) map[K]V {
mm := make(map[K]V, 0)
for k, v := range m {
key, val, ok := fn(k, v)
if ok {
mm[key] = val
}
}
return mm
}

View File

@ -7,6 +7,7 @@ import (
"io" "io"
"strconv" "strconv"
"strings" "strings"
"unicode"
) )
func Join(s ...string) (str string) { func Join(s ...string) (str string) {
@ -94,3 +95,19 @@ func (b *Builder) Sprintf(format string, a ...any) int {
func CutSpecialDuplicate(s, char string) string { func CutSpecialDuplicate(s, char string) string {
return strings.Join(strings.Fields(s), char) return strings.Join(strings.Fields(s), char)
} }
// CamelCaseTo 驼峰单词转下划线或横杠单词 //分隔符
func CamelCaseTo(s string, delimiter rune) string {
var output []rune
for i, r := range s {
if i == 0 {
output = append(output, unicode.ToLower(r))
} else {
if unicode.IsUpper(r) {
output = append(output, delimiter)
}
output = append(output, unicode.ToLower(r))
}
}
return string(output)
}

View File

@ -73,13 +73,25 @@ func Roots[T any, K comparable](a []T, top K, fn func(T) (child, parent K)) map[
return root(a, top, fn) return root(a, top, fn)
} }
type nod[K comparable] struct {
current K
parent K
}
func root[T any, K comparable](a []T, top K, fn func(T) (child, parent K)) map[K]*Node[T, K] { func root[T any, K comparable](a []T, top K, fn func(T) (child, parent K)) map[K]*Node[T, K] {
m := make(map[K]*Node[T, K]) m := make(map[K]*Node[T, K])
mm := make(map[int]nod[K])
m[top] = &Node[T, K]{Children: new([]Node[T, K])} m[top] = &Node[T, K]{Children: new([]Node[T, K])}
for _, t := range a { for i, t := range a {
c, p := fn(t) c, p := fn(t)
node := Node[T, K]{Parent: p, Data: t, Children: new([]Node[T, K])} node := Node[T, K]{Parent: p, Data: t, Children: new([]Node[T, K])}
m[c] = &node m[c] = &node
mm[i] = nod[K]{c, p}
}
for i := range a {
c := mm[i].current
p := mm[i].parent
node := *m[c]
parent, ok := m[p] parent, ok := m[p]
if !ok { if !ok {
m[p] = &Node[T, K]{Children: new([]Node[T, K])} m[p] = &Node[T, K]{Children: new([]Node[T, K])}

View File

@ -0,0 +1,10 @@
package blocks
const (
Search = "block-search"
RecentPosts = "block-recent-posts"
RecentComments = "block-recent-comments"
Archive = "block-archives"
Categories = "block-categories"
Meta = "block-meta"
)

View File

@ -1,12 +1,12 @@
package widgets package widgets
const ( const (
Search = "search" Search = "widget-search"
RecentPosts = "recent-posts" RecentPosts = "widget-recent-posts"
RecentComments = "recent-comments" RecentComments = "widget-recent-comments"
Archive = "archives" Archive = "widget-archives"
Categories = "categories" Categories = "widget-categories"
Meta = "meta" Meta = "widget-meta"
Widget = "widget" Widget = "widget"
) )

View File

@ -36,10 +36,10 @@ func CategoriesAndTags(a ...any) (terms []models.TermsMy, err error) {
w := model.SqlBuilder{ w := model.SqlBuilder{
{"tt.taxonomy", "in", ""}, {"tt.taxonomy", "in", ""},
} }
if helper.GetContextVal(ctx, "onlyTop", false) { if helper.GetContextVal(ctx, "showOnlyTopLevel", false) {
w = append(w, []string{"tt.parent", "=", "0", "int"}) w = append(w, []string{"tt.parent", "=", "0", "int"})
} }
if !helper.GetContextVal(ctx, "showCountZero", false) { if !helper.GetContextVal(ctx, "showEmpty", false) {
w = append(w, []string{"tt.count", ">", "0", "int"}) w = append(w, []string{"tt.count", ">", "0", "int"})
} }
order := []string{"name", "asc"} order := []string{"name", "asc"}

View File

@ -7,7 +7,7 @@ import (
) )
func HiddenLogin(h *wp.Handle) { func HiddenLogin(h *wp.Handle) {
h.PushComponentFilterFn(widgets.Meta, func(h *wp.Handle, s string) string { h.PushComponentFilterFn(widgets.Meta, func(h *wp.Handle, s string, args ...any) string {
return str.Replace(s, map[string]string{ return str.Replace(s, map[string]string{
`<li><a href="/wp-login.php">登录</a></li>`: "", `<li><a href="/wp-login.php">登录</a></li>`: "",
`<li><a href="/feed">登录</a></li>`: "", `<li><a href="/feed">登录</a></li>`: "",

741
internal/static/wp-includes/css/dist/block-library/style.css vendored Executable file → Normal file

File diff suppressed because it is too large Load Diff

6
internal/static/wp-includes/css/dist/block-library/style.min.css vendored Executable file → Normal file

File diff suppressed because one or more lines are too long

View File

@ -42,7 +42,7 @@ func Hook(h *wp.Handle) {
func ready(next wp.HandleFn[*wp.Handle], h *wp.Handle) { func ready(next wp.HandleFn[*wp.Handle], h *wp.Handle) {
h.GetPassword() h.GetPassword()
h.PushComponentFilterFn(widgets.Search, func(h *wp.Handle, s string) string { h.PushComponentFilterFn(widgets.Search, func(h *wp.Handle, s string, args ...any) string {
return strings.ReplaceAll(s, `class="search-submit"`, `class="search-submit screen-reader-text"`) return strings.ReplaceAll(s, `class="search-submit"`, `class="search-submit screen-reader-text"`)
}) })
wphandle.RegisterPlugins(h, config.GetConfig().Plugins...) wphandle.RegisterPlugins(h, config.GetConfig().Plugins...)

View File

@ -61,7 +61,7 @@ func ready(next wp.HandleFn[*wp.Handle], h *wp.Handle) {
pushScripts(h) pushScripts(h)
h.SetData("HeaderImage", getHeaderImage(h)) h.SetData("HeaderImage", getHeaderImage(h))
h.SetComponentsArgs(widgets.Widget, map[string]string{ h.SetComponentsArgs(widgets.Widget, map[string]string{
"{$before_widget}": `<section id="%s" class="widget widget_%s">`, "{$before_widget}": `<section id="%s" class="%s">`,
"{$after_widget}": `</section>`, "{$after_widget}": `</section>`,
}) })
wp.SetComponentsArgsForMap(h, widgets.Search, "{$form}", searchForm) wp.SetComponentsArgsForMap(h, widgets.Search, "{$form}", searchForm)

View File

@ -0,0 +1,35 @@
package components
import (
str "github.com/fthvgb1/wp-go/helper/strings"
"github.com/fthvgb1/wp-go/internal/theme/wp"
"github.com/fthvgb1/wp-go/internal/theme/wp/components/block"
"github.com/fthvgb1/wp-go/internal/wpconfig"
"strings"
)
var blockFn = map[string]func(*wp.Handle, string, block.ParserBlock, map[string]string) (func() string, error){
"core/categories": block.Category,
}
func Block(id string, args map[string]string) func(*wp.Handle) string {
content := wpconfig.GetPHPArrayVal("widget_block", "", str.ToInteger[int64](id, 0), "content")
if content == "" {
return nil
}
v := block.ParseBlock(content)
return func(h *wp.Handle) string {
var out []string
for _, parserBlock := range v.Output {
fn, ok := blockFn[parserBlock.Name]
if ok {
s, err := fn(h, id, parserBlock, args)
if err != nil {
continue
}
out = append(out, s())
}
}
return strings.Join(out, "\n")
}
}

View File

@ -0,0 +1,96 @@
package block
import (
"github.com/dlclark/regexp2"
str "github.com/fthvgb1/wp-go/helper/strings"
)
type Block struct {
Name string
Attrs string
Len int
StartOffset int
Type string
}
type BockParser struct {
Document string
Offset int
Output []ParserBlock
}
type ParserBlock struct {
Name string
Attrs string
InnerBlocks string
InnerHtml string
InnerContent string
}
var block = regexp2.MustCompile(`<!--\s+(?<closer>/)?wp:(?<namespace>[a-z][a-z0-9_-]*\/)?(?<name>[a-z][a-z0-9_-]*)\s+(?<attrs>{(?:(?:[^}]+|}+(?=})|(?!}\s+\/?-->).)*)?}\s+)?(?<void>\/)?-->`, regexp2.IgnoreCase|regexp2.Singleline)
func ParseBlock(content string) (r BockParser) {
m, err := block.FindStringMatch(content)
if err != nil {
panic(err)
}
r.Document = content
for m != nil {
if m.GroupCount() < 1 {
continue
}
b := token(m.Groups())
bb := ParserBlock{}
bb.Name = b.Name
bb.Attrs = b.Attrs
r.Output = append(r.Output, bb)
m, _ = block.FindNextMatch(m)
}
return
}
func token(g []regexp2.Group) (b Block) {
if len(g) < 1 {
b.Type = "no-more-tokens"
return
}
var closer, name, void, nameSpace = "", "", "", ""
for i, group := range g {
v := group.String()
if v == "" {
continue
}
switch i {
case 0:
b.Len = group.Length
b.StartOffset = group.Index
case 1:
closer = v
case 2:
nameSpace = v
case 3:
name = v
case 4:
b.Attrs = v
case 5:
void = v
default:
continue
}
}
if nameSpace == "" {
nameSpace = "core/"
}
b.Name = str.Join(nameSpace, name)
if void != "" {
b.Type = "void-block"
return
}
if closer != "" {
b.Type = "block-closer"
return
}
b.Type = "block-opener"
return b
}

View File

@ -0,0 +1,25 @@
package block
import "testing"
func TestParseBlock(t *testing.T) {
type args struct {
s string
}
tests := []struct {
name string
args args
}{
{
name: "t1",
args: args{
s: `<!-- wp:categories {"showPostCounts":true,"showEmpty":true} /-->`,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ParseBlock(tt.args.s)
})
}
}

View File

@ -0,0 +1,179 @@
package block
import (
"encoding/json"
"errors"
"fmt"
"github.com/fthvgb1/wp-go/helper/maps"
"github.com/fthvgb1/wp-go/helper/number"
str "github.com/fthvgb1/wp-go/helper/strings"
"github.com/fthvgb1/wp-go/internal/cmd/reload"
"github.com/fthvgb1/wp-go/internal/pkg/cache"
constraints2 "github.com/fthvgb1/wp-go/internal/pkg/constraints"
"github.com/fthvgb1/wp-go/internal/pkg/logs"
"github.com/fthvgb1/wp-go/internal/pkg/models"
"github.com/fthvgb1/wp-go/internal/theme/wp"
"github.com/fthvgb1/wp-go/internal/theme/wp/components/widget"
"strings"
)
func categoryConf() map[any]any {
return map[any]any{
"count": int64(0),
"dropdown": int64(0),
"hierarchical": int64(0),
"title": "分类",
}
}
func categoryDefaultArgs() map[string]string {
return map[string]string{
"{$before_widget}": `<aside id="%s" class="%s">`,
"{$after_widget}": `</aside>`,
"{$name}": "cat",
"{$class}": "postform",
"{$selectId}": "cat",
"{$required}": "",
"{$show_option_none}": "选择分类",
"{$title}": "",
}
}
func parseAttr(attr map[any]any) string {
var attrs []string
class := maps.GetAnyAnyValWithDefaults(attr, "", "className")
classes := strings.Split(class, " ")
fontsize := maps.GetAnyAnyValWithDefaults(attr, "", "fontSize")
if fontsize != "" {
classes = append(classes, fmt.Sprintf("has-%s-font-size", fontsize))
}
style := maps.GetAnyAnyValWithDefaults[map[any]any](attr, nil, "style", "typography")
if len(style) > 0 {
styless := maps.AnyAnyMap(style, func(k, v any) (string, string, bool) {
kk, ok := k.(string)
if !ok {
return "", "", false
}
vv, ok := v.(string)
if !ok {
return "", "", false
}
return kk, vv, true
})
styles := maps.FilterToSlice(styless, func(k string, v string) (string, bool) {
k = str.CamelCaseTo(k, '-')
return str.Join(k, ":", v), true
})
attrs = append(attrs, fmt.Sprintf(`style="%s;"`, strings.Join(styles, ";")))
}
attrs = append(attrs, fmt.Sprintf(`class="%s"`, strings.Join(classes, " ")))
return strings.Join(attrs, " ")
}
func Category(h *wp.Handle, id string, blockParser ParserBlock, args map[string]string) (func() string, error) {
counter := number.Counters[int]()
var err error
conf := reload.GetAnyValBys("block-category-conf", h, func(h *wp.Handle) map[any]any {
var con any
err = json.Unmarshal([]byte(blockParser.Attrs), &con)
if err != nil {
logs.ErrPrintln(err, "解析category attr错误", blockParser.Attrs)
return nil
}
var conf map[any]any
switch con.(type) {
case map[any]any:
conf = con.(map[any]any)
case map[string]any:
conf = maps.StrAnyToAnyAny(con.(map[string]any))
}
conf = maps.FilterZeroMerge(categoryConf(), conf)
if maps.GetAnyAnyValWithDefaults(conf, false, "showPostCounts") {
conf["count"] = int64(1)
}
if maps.GetAnyAnyValWithDefaults(conf, false, "displayAsDropdown") {
conf["dropdown"] = int64(1)
}
if maps.GetAnyAnyValWithDefaults(conf, false, "showHierarchy") {
conf["hierarchical"] = int64(1)
}
return conf
})
if err != nil {
return nil, err
}
if conf == nil {
return nil, errors.New("解析block-category配置错误")
}
if maps.GetAnyAnyValWithDefaults(conf, false, "showEmpty") {
h.C.Set("showEmpty", true)
}
if maps.GetAnyAnyValWithDefaults(conf, false, "showOnlyTopLevel") {
h.C.Set("showOnlyTopLevel", true)
}
args = reload.GetAnyValBys("block-category-args", h, func(h *wp.Handle) map[string]string {
return maps.FilterZeroMerge(categoryDefaultArgs(), args)
})
return func() string {
return category(h, id, counter, args, conf)
}, nil
}
func category(h *wp.Handle, id string, counter number.Counter[int], args map[string]string, conf map[any]any) string {
var out = ""
categories := cache.CategoriesTags(h.C, constraints2.Category)
class := []string{"widget", "widget_block", "widget_categories"}
classx := maps.GetAnyAnyValWithDefaults(conf, "", "className")
classes := strings.Split(classx, " ")
classes = append(classes, "wp-block-categories")
if conf["dropdown"].(int64) == 1 {
classes = append(classes, "wp-block-categories-dropdown")
conf["className"] = strings.Join(classes, " ")
out = dropdown(h, categories, counter(), args, conf)
} else {
classes = append(classes, "wp-block-categories-list")
conf["className"] = strings.Join(classes, " ")
out = categoryUl(h, categories, conf)
}
before := fmt.Sprintf(args["{$before_widget}"], str.Join("block-", id), strings.Join(class, " "))
return str.Join(before, out, args["{$after_widget}"])
}
func categoryUl(h *wp.Handle, categories []models.TermsMy, conf map[any]any) string {
s := str.NewBuilder()
li := widget.CategoryLi(h, conf, categories)
attrs := reload.GetAnyValBys("block-category-attr", conf, parseAttr)
s.Sprintf(`<ul %s>%s</ul>`, attrs, li)
return s.String()
}
func dropdown(h *wp.Handle, categories []models.TermsMy, id int, args map[string]string, conf map[any]any) string {
s := str.NewBuilder()
ids := fmt.Sprintf(`wp-block-categories-%v`, id)
args["{$selectId}"] = ids
attrs := reload.GetAnyValBys("block-category-attr", conf, parseAttr)
selects := widget.DropdownCategories(h, args, conf, categories)
s.Sprintf(`<div %s><label class="screen-reader-text" for="%s">%s</label>%s%s</div>`, attrs, ids, args["{$title}"], selects, strings.ReplaceAll(categoryDropdownScript, "{$id}", ids))
return s.String()
}
var categoryDropdownScript = `
<script type='text/javascript'>
/* <![CDATA[ */
( function() {
const dropdown = document.getElementById( '{$id}' );
function onCatChange() {
if ( dropdown.options[ dropdown.selectedIndex ].value > 0 ) {
location.href = "/?cat=" + dropdown.options[ dropdown.selectedIndex ].value;
}
}
dropdown.onchange = onCatChange;
})();
/* ]]> */
</script>
`

View File

@ -5,6 +5,7 @@ import (
"github.com/fthvgb1/wp-go/helper/maps" "github.com/fthvgb1/wp-go/helper/maps"
"github.com/fthvgb1/wp-go/helper/slice" "github.com/fthvgb1/wp-go/helper/slice"
str "github.com/fthvgb1/wp-go/helper/strings" str "github.com/fthvgb1/wp-go/helper/strings"
"github.com/fthvgb1/wp-go/internal/cmd/reload"
"github.com/fthvgb1/wp-go/internal/pkg/cache" "github.com/fthvgb1/wp-go/internal/pkg/cache"
"github.com/fthvgb1/wp-go/internal/pkg/constraints/widgets" "github.com/fthvgb1/wp-go/internal/pkg/constraints/widgets"
"github.com/fthvgb1/wp-go/internal/pkg/models" "github.com/fthvgb1/wp-go/internal/pkg/models"
@ -47,11 +48,19 @@ func archivesConfig() map[any]any {
} }
func Archive(h *wp.Handle) string { func Archive(h *wp.Handle) string {
args := reload.GetAnyValBys("widget-archive-args", h, func(h *wp.Handle) map[string]string {
archiveArgs := archiveArgs() archiveArgs := archiveArgs()
archivesConfig := archivesConfig()
args := wp.GetComponentsArgs(h, widgets.Archive, archiveArgs) args := wp.GetComponentsArgs(h, widgets.Archive, archiveArgs)
args = maps.FilterZeroMerge(archiveArgs, args) args = maps.FilterZeroMerge(archiveArgs, args)
return args
})
conf := reload.GetAnyValBys("widget-archive-conf", h, func(h *wp.Handle) map[any]any {
archivesConfig := archivesConfig()
conf := wpconfig.GetPHPArrayVal("widget_archives", archivesConfig, int64(2)) conf := wpconfig.GetPHPArrayVal("widget_archives", archivesConfig, int64(2))
return conf
})
args["{$title}"] = str.Join(args["{$before_title}"], conf["title"].(string), args["{$after_title}"]) args["{$title}"] = str.Join(args["{$before_title}"], conf["title"].(string), args["{$after_title}"])
if id, ok := args["{$id}"]; ok && id != "" { if id, ok := args["{$id}"]; ok && id != "" {
args["{$before_widget}"] = strings.ReplaceAll(args["{$before_widget}"], "2", args["{$id}"]) args["{$before_widget}"] = strings.ReplaceAll(args["{$before_widget}"], "2", args["{$id}"])

View File

@ -6,6 +6,7 @@ import (
"github.com/fthvgb1/wp-go/helper/slice" "github.com/fthvgb1/wp-go/helper/slice"
str "github.com/fthvgb1/wp-go/helper/strings" str "github.com/fthvgb1/wp-go/helper/strings"
"github.com/fthvgb1/wp-go/helper/tree" "github.com/fthvgb1/wp-go/helper/tree"
"github.com/fthvgb1/wp-go/internal/cmd/reload"
"github.com/fthvgb1/wp-go/internal/pkg/cache" "github.com/fthvgb1/wp-go/internal/pkg/cache"
"github.com/fthvgb1/wp-go/internal/pkg/constraints" "github.com/fthvgb1/wp-go/internal/pkg/constraints"
"github.com/fthvgb1/wp-go/internal/pkg/constraints/widgets" "github.com/fthvgb1/wp-go/internal/pkg/constraints/widgets"
@ -49,17 +50,21 @@ func categoryArgs() map[string]string {
"{$nav}": "", "{$nav}": "",
"{$navCloser}": "", "{$navCloser}": "",
"{$title}": "", "{$title}": "",
"{$dropdown_id}": "archives-dropdown-2",
"{$dropdown_type}": "monthly",
"{$dropdown_label}": "选择月份",
} }
} }
func Category(h *wp.Handle) string { func Category(h *wp.Handle) string {
args := reload.GetAnyValBys("widget-category-args", h, func(h *wp.Handle) map[string]string {
args := wp.GetComponentsArgs(h, widgets.Categories, categoryArgs()) args := wp.GetComponentsArgs(h, widgets.Categories, categoryArgs())
args = maps.FilterZeroMerge(categoryArgs(), args) args = maps.FilterZeroMerge(categoryArgs(), args)
return args
})
conf := reload.GetAnyValBys("widget-category-conf", h, func(a *wp.Handle) map[any]any {
conf := wpconfig.GetPHPArrayVal("widget_categories", categoryConfig(), int64(2)) conf := wpconfig.GetPHPArrayVal("widget_categories", categoryConfig(), int64(2))
conf = maps.FilterZeroMerge(categoryConfig(), conf) conf = maps.FilterZeroMerge(categoryConfig(), conf)
return conf
})
args["{$title}"] = str.Join(args["{$before_title}"], conf["title"].(string), args["{$after_title}"]) args["{$title}"] = str.Join(args["{$before_title}"], conf["title"].(string), args["{$after_title}"])
t := categoryTemplate t := categoryTemplate
dropdown := conf["dropdown"].(int64) dropdown := conf["dropdown"].(int64)
@ -68,7 +73,7 @@ func Category(h *wp.Handle) string {
} }
categories := cache.CategoriesTags(h.C, constraints.Category) categories := cache.CategoriesTags(h.C, constraints.Category)
if dropdown == 1 { if dropdown == 1 {
t = strings.ReplaceAll(t, "{$html}", categoryDropdown(h, args, conf, categories)) t = strings.ReplaceAll(t, "{$html}", CategoryDropdown(h, args, conf, categories))
} else { } else {
t = strings.ReplaceAll(t, "{$html}", categoryUL(h, args, conf, categories)) t = strings.ReplaceAll(t, "{$html}", categoryUL(h, args, conf, categories))
@ -181,16 +186,33 @@ var categoryDropdownJs = `/* <![CDATA[ */
/* ]]> */ /* ]]> */
` `
func categoryDropdown(h *wp.Handle, args map[string]string, conf map[any]any, categories []models.TermsMy) string { func CategoryDropdown(h *wp.Handle, args map[string]string, conf map[any]any, categories []models.TermsMy) string {
s := str.NewBuilder() s := str.NewBuilder()
s.WriteString(`<form action="/" method="get"> s.WriteString(`<form action="/" method="get">
`) `)
s.Sprintf(` <label class="screen-reader-text" for="%s">%s</label> s.Sprintf(` <label class="screen-reader-text" for="%s">%s</label>
`, args["{$selectId}"], args["{$title}"]) `, args["{$selectId}"], args["{$title}"])
if len(categories) > 0 { s.WriteString(DropdownCategories(h, args, conf, categories))
s.WriteString("</form>\n")
attr := ""
if !slice.IsContained(h.CommonThemeMods().ThemeSupport.HTML5, "script") {
attr = ` type="text/javascript"`
}
s.Sprintf(`<script%s>
`, attr)
s.Sprintf(categoryDropdownJs, args["{$selectId}"])
s.WriteString("</script>\n")
return s.String()
}
func DropdownCategories(h *wp.Handle, args map[string]string, conf map[any]any, categories []models.TermsMy) string {
if len(categories) < 1 {
return ""
}
s := str.NewBuilder()
s.Sprintf(` <select %s name="%s" id="%s" class="%s"> s.Sprintf(` <select %s name="%s" id="%s" class="%s">
`, args["{$required}"], args["{$name}"], args["{$selectId}"], args["{$class}"]) `, args["{$required}"], args["{$name}"], args["{$selectId}"], args["{$class}"])
s.Sprintf(` <option value="%[1]s">%[1]s</option> s.Sprintf(` <option value="-1">%s</option>
`, args["{$show_option_none}"]) `, args["{$show_option_none}"])
currentCategory := "" currentCategory := ""
if h.Scene() == constraints.Category { if h.Scene() == constraints.Category {
@ -223,17 +245,7 @@ func categoryDropdown(h *wp.Handle, args map[string]string, conf map[any]any, ca
}) })
} }
s.WriteString(" </select>\n") s.WriteString(" </select>\n")
} return h.ComponentFilterFnHook("wp_dropdown_cats", s.String())
s.WriteString("</form>\n")
attr := ""
if !slice.IsContained(h.CommonThemeMods().ThemeSupport.HTML5, "script") {
attr = ` type="text/javascript"`
}
s.Sprintf(`<script%s>
`, attr)
s.Sprintf(categoryDropdownJs, args["{$selectId}"])
s.WriteString("</script>\n")
return s.String()
} }
func IsCategory(next wp.HandleFn[*wp.Handle], h *wp.Handle) { func IsCategory(next wp.HandleFn[*wp.Handle], h *wp.Handle) {

View File

@ -5,6 +5,7 @@ import (
"github.com/fthvgb1/wp-go/helper/maps" "github.com/fthvgb1/wp-go/helper/maps"
"github.com/fthvgb1/wp-go/helper/slice" "github.com/fthvgb1/wp-go/helper/slice"
str "github.com/fthvgb1/wp-go/helper/strings" str "github.com/fthvgb1/wp-go/helper/strings"
"github.com/fthvgb1/wp-go/internal/cmd/reload"
"github.com/fthvgb1/wp-go/internal/pkg/constraints/widgets" "github.com/fthvgb1/wp-go/internal/pkg/constraints/widgets"
"github.com/fthvgb1/wp-go/internal/theme/wp" "github.com/fthvgb1/wp-go/internal/theme/wp"
"github.com/fthvgb1/wp-go/internal/wpconfig" "github.com/fthvgb1/wp-go/internal/wpconfig"
@ -33,9 +34,12 @@ func metaArgs() map[string]string {
} }
func Meta(h *wp.Handle) string { func Meta(h *wp.Handle) string {
args := reload.GetAnyValBys("widget-meta-args", h, func(h *wp.Handle) map[string]string {
metaArgs := metaArgs() metaArgs := metaArgs()
args := wp.GetComponentsArgs(h, widgets.Meta, metaArgs) args := wp.GetComponentsArgs(h, widgets.Meta, metaArgs)
args = maps.FilterZeroMerge(metaArgs, args) args = maps.FilterZeroMerge(metaArgs, args)
return args
})
args["{$title}"] = wpconfig.GetPHPArrayVal("widget_meta", "其它操作", int64(2), "title") args["{$title}"] = wpconfig.GetPHPArrayVal("widget_meta", "其它操作", int64(2), "title")
if id, ok := args["{$id}"]; ok && id != "" { if id, ok := args["{$id}"]; ok && id != "" {
args["{$before_widget}"] = strings.ReplaceAll(args["{$before_widget}"], "2", args["{$id}"]) args["{$before_widget}"] = strings.ReplaceAll(args["{$before_widget}"], "2", args["{$id}"])

View File

@ -5,6 +5,7 @@ import (
"github.com/fthvgb1/wp-go/helper/maps" "github.com/fthvgb1/wp-go/helper/maps"
"github.com/fthvgb1/wp-go/helper/slice" "github.com/fthvgb1/wp-go/helper/slice"
str "github.com/fthvgb1/wp-go/helper/strings" str "github.com/fthvgb1/wp-go/helper/strings"
"github.com/fthvgb1/wp-go/internal/cmd/reload"
"github.com/fthvgb1/wp-go/internal/pkg/cache" "github.com/fthvgb1/wp-go/internal/pkg/cache"
"github.com/fthvgb1/wp-go/internal/pkg/constraints/widgets" "github.com/fthvgb1/wp-go/internal/pkg/constraints/widgets"
"github.com/fthvgb1/wp-go/internal/pkg/models" "github.com/fthvgb1/wp-go/internal/pkg/models"
@ -46,12 +47,20 @@ var recentCommentsTemplate = `{$before_widget}
` `
func RecentComments(h *wp.Handle) string { func RecentComments(h *wp.Handle) string {
recentCommentsArgs := recentCommentsArgs() args := reload.GetAnyValBys("widget-recent-comment-args", h, func(h *wp.Handle) map[string]string {
recentCommentConf := recentCommentConf() commentsArgs := recentCommentsArgs()
args := wp.GetComponentsArgs(h, widgets.RecentComments, recentCommentsArgs) args := wp.GetComponentsArgs(h, widgets.RecentComments, commentsArgs)
args = maps.FilterZeroMerge(recentCommentsArgs, args) args = maps.FilterZeroMerge(commentsArgs, args)
conf := wpconfig.GetPHPArrayVal("widget_recent-comments", recentCommentConf, int64(2)) return args
conf = maps.FilterZeroMerge(recentCommentConf, conf) })
conf := reload.GetAnyValBys("widget-recent-comment-conf", h, func(h *wp.Handle) map[any]any {
commentConf := recentCommentConf()
conf := wpconfig.GetPHPArrayVal("widget_recent-comments", commentConf, int64(2))
conf = maps.FilterZeroMerge(commentConf, conf)
return conf
})
args["{$title}"] = str.Join(args["{$before_title}"], conf["title"].(string), args["{$after_title}"]) args["{$title}"] = str.Join(args["{$before_title}"], conf["title"].(string), args["{$after_title}"])
if id, ok := args["{$id}"]; ok && id != "" { if id, ok := args["{$id}"]; ok && id != "" {
args["{$before_widget}"] = strings.ReplaceAll(args["{$before_widget}"], "2", args["{$id}"]) args["{$before_widget}"] = strings.ReplaceAll(args["{$before_widget}"], "2", args["{$id}"])

View File

@ -5,6 +5,7 @@ import (
"github.com/fthvgb1/wp-go/helper/maps" "github.com/fthvgb1/wp-go/helper/maps"
"github.com/fthvgb1/wp-go/helper/slice" "github.com/fthvgb1/wp-go/helper/slice"
str "github.com/fthvgb1/wp-go/helper/strings" str "github.com/fthvgb1/wp-go/helper/strings"
"github.com/fthvgb1/wp-go/internal/cmd/reload"
"github.com/fthvgb1/wp-go/internal/pkg/cache" "github.com/fthvgb1/wp-go/internal/pkg/cache"
"github.com/fthvgb1/wp-go/internal/pkg/constraints" "github.com/fthvgb1/wp-go/internal/pkg/constraints"
"github.com/fthvgb1/wp-go/internal/pkg/constraints/widgets" "github.com/fthvgb1/wp-go/internal/pkg/constraints/widgets"
@ -47,12 +48,19 @@ func recentConf() map[any]any {
} }
func RecentPosts(h *wp.Handle) string { func RecentPosts(h *wp.Handle) string {
recentPostsArgs := recentPostsArgs() args := reload.GetAnyValBys("widget-recent-posts-args", h, func(h *wp.Handle) map[string]string {
recentConf := recentConf() recent := recentPostsArgs()
args := wp.GetComponentsArgs(h, widgets.RecentPosts, recentPostsArgs) args := wp.GetComponentsArgs(h, widgets.RecentPosts, recent)
args = maps.FilterZeroMerge(recentPostsArgs, args) args = maps.FilterZeroMerge(recent, args)
conf := wpconfig.GetPHPArrayVal[map[any]any]("widget_recent-posts", recentConf, int64(2)) return args
conf = maps.FilterZeroMerge(recentConf, conf) })
conf := reload.GetAnyValBys("widget-recent-posts-conf", h, func(h *wp.Handle) map[any]any {
recent := recentConf()
conf := wpconfig.GetPHPArrayVal[map[any]any]("widget_recent-posts", recent, int64(2))
conf = maps.FilterZeroMerge(recent, conf)
return conf
})
if id, ok := args["{$id}"]; ok && id != "" { if id, ok := args["{$id}"]; ok && id != "" {
args["{$before_widget}"] = strings.ReplaceAll(args["{$before_widget}"], "2", args["{$id}"]) args["{$before_widget}"] = strings.ReplaceAll(args["{$before_widget}"], "2", args["{$id}"])
} }

View File

@ -5,6 +5,7 @@ import (
"github.com/fthvgb1/wp-go/helper/maps" "github.com/fthvgb1/wp-go/helper/maps"
"github.com/fthvgb1/wp-go/helper/slice" "github.com/fthvgb1/wp-go/helper/slice"
str "github.com/fthvgb1/wp-go/helper/strings" str "github.com/fthvgb1/wp-go/helper/strings"
"github.com/fthvgb1/wp-go/internal/cmd/reload"
"github.com/fthvgb1/wp-go/internal/pkg/constraints" "github.com/fthvgb1/wp-go/internal/pkg/constraints"
"github.com/fthvgb1/wp-go/internal/pkg/constraints/widgets" "github.com/fthvgb1/wp-go/internal/pkg/constraints/widgets"
"github.com/fthvgb1/wp-go/internal/theme/wp" "github.com/fthvgb1/wp-go/internal/theme/wp"
@ -49,9 +50,12 @@ func searchArgs() map[string]string {
} }
func Search(h *wp.Handle) string { func Search(h *wp.Handle) string {
searchArgs := searchArgs() args := reload.GetAnyValBys("widget-search-args", h, func(h *wp.Handle) map[string]string {
args := wp.GetComponentsArgs(h, widgets.Search, searchArgs) search := searchArgs()
args = maps.FilterZeroMerge(searchArgs, args) args := wp.GetComponentsArgs(h, widgets.Search, search)
args = maps.FilterZeroMerge(search, args)
return args
})
if args["{$title}"] == "" { if args["{$title}"] == "" {
args["{$title}"] = wpconfig.GetPHPArrayVal("widget_search", "", int64(2), "title") args["{$title}"] = wpconfig.GetPHPArrayVal("widget_search", "", int64(2), "title")
} }

View File

@ -3,8 +3,8 @@ package components
import ( import (
"fmt" "fmt"
"github.com/fthvgb1/wp-go/helper/slice" "github.com/fthvgb1/wp-go/helper/slice"
str "github.com/fthvgb1/wp-go/helper/strings"
"github.com/fthvgb1/wp-go/internal/cmd/reload" "github.com/fthvgb1/wp-go/internal/cmd/reload"
"github.com/fthvgb1/wp-go/internal/pkg/cache"
"github.com/fthvgb1/wp-go/internal/pkg/constraints" "github.com/fthvgb1/wp-go/internal/pkg/constraints"
"github.com/fthvgb1/wp-go/internal/pkg/constraints/widgets" "github.com/fthvgb1/wp-go/internal/pkg/constraints/widgets"
"github.com/fthvgb1/wp-go/internal/theme/wp" "github.com/fthvgb1/wp-go/internal/theme/wp"
@ -25,7 +25,6 @@ var widgetFn = map[string]wp.Components[string]{
func WidgetArea(h *wp.Handle) { func WidgetArea(h *wp.Handle) {
sidebar := reload.GetAnyValBys("sidebarWidgets", h, sidebars) sidebar := reload.GetAnyValBys("sidebarWidgets", h, sidebars)
h.PushComponents(constraints.SidebarsWidgets, sidebar...) h.PushComponents(constraints.SidebarsWidgets, sidebar...)
h.SetData("categories", cache.CategoriesTags(h.C, constraints.Category))
} }
func sidebars(h *wp.Handle) []wp.Components[string] { func sidebars(h *wp.Handle) []wp.Components[string] {
@ -33,8 +32,6 @@ func sidebars(h *wp.Handle) []wp.Components[string] {
beforeWidget, ok := args["{$before_widget}"] beforeWidget, ok := args["{$before_widget}"]
if !ok { if !ok {
beforeWidget = "" beforeWidget = ""
} else {
delete(args, "{$before_widget}")
} }
v := wpconfig.GetPHPArrayVal("sidebars_widgets", []any{}, "sidebar-1") v := wpconfig.GetPHPArrayVal("sidebars_widgets", []any{}, "sidebar-1")
return slice.FilterAndMap(v, func(t any) (wp.Components[string], bool) { return slice.FilterAndMap(v, func(t any) (wp.Components[string], bool) {
@ -43,21 +40,34 @@ func sidebars(h *wp.Handle) []wp.Components[string] {
id := ss[len(ss)-1] id := ss[len(ss)-1]
name := strings.Join(ss[0:len(ss)-1], "-") name := strings.Join(ss[0:len(ss)-1], "-")
components, ok := widgetFn[name] components, ok := widgetFn[name]
if !ok { if name != "block" && !ok {
return components, false return components, false
} }
if id != "2" { if id != "2" {
wp.SetComponentsArgsForMap(h, name, "{$id}", id) wp.SetComponentsArgsForMap(h, name, "{$id}", id)
} }
if beforeWidget != "" { names := str.Join("widget-", name)
if beforeWidget != "" && name != "block" {
n := strings.ReplaceAll(name, "-", "_") n := strings.ReplaceAll(name, "-", "_")
if name == "recent-posts" { if name == "recent-posts" {
n = "recent_entries" n = "recent_entries"
} }
wp.SetComponentsArgsForMap(h, name, "{$before_widget}", fmt.Sprintf(beforeWidget, vv, n)) n = str.Join("widget widget_", n)
delete(args, "{$before_widget}")
wp.SetComponentsArgsForMap(h, names, "{$before_widget}", fmt.Sprintf(beforeWidget, vv, n))
} else {
args["{$before_widget}"] = beforeWidget
} }
for k, val := range args { for k, val := range args {
wp.SetComponentsArgsForMap(h, name, k, val) wp.SetComponentsArgsForMap(h, names, k, val)
}
if name == "block" {
fn := Block(id, args)
if fn == nil {
return wp.Components[string]{}, false
}
components = wp.Components[string]{Fn: fn, Order: 10}
} }
components.Order = 10 components.Order = 10
return components, true return components, true

View File

@ -33,7 +33,7 @@ type Handle struct {
err error err error
abort bool abort bool
componentsArgs map[string]any componentsArgs map[string]any
componentFilterFn map[string][]func(*Handle, string) string componentFilterFn map[string][]func(*Handle, string, ...any) string
} }
type HandlePlugins map[string]HandleFn[*Handle] type HandlePlugins map[string]HandleFn[*Handle]
@ -55,19 +55,19 @@ type HandleCall struct {
Order int Order int
} }
func (h *Handle) ComponentFilterFn(name string) ([]func(*Handle, string) string, bool) { func (h *Handle) ComponentFilterFn(name string) ([]func(*Handle, string, ...any) string, bool) {
fn, ok := h.componentFilterFn[name] fn, ok := h.componentFilterFn[name]
return fn, ok return fn, ok
} }
func (h *Handle) PushComponentFilterFn(name string, fns ...func(*Handle, string) string) { func (h *Handle) PushComponentFilterFn(name string, fns ...func(*Handle, string, ...any) string) {
h.componentFilterFn[name] = append(h.componentFilterFn[name], fns...) h.componentFilterFn[name] = append(h.componentFilterFn[name], fns...)
} }
func (h *Handle) ComponentFilterFnHook(name, s string) string { func (h *Handle) ComponentFilterFnHook(name, s string, args ...any) string {
calls, ok := h.componentFilterFn[name] calls, ok := h.componentFilterFn[name]
if ok { if ok {
return slice.Reduce(calls, func(fn func(*Handle, string) string, r string) string { return slice.Reduce(calls, func(fn func(*Handle, string, ...any) string, r string) string {
return fn(h, r) return fn(h, r, args...)
}, s) }, s)
} }
return s return s
@ -181,7 +181,7 @@ func NewHandle(c *gin.Context, scene int, theme string) *Handle {
components: make(map[string][]Components[string]), components: make(map[string][]Components[string]),
handleFns: make(map[int][]HandleCall), handleFns: make(map[int][]HandleCall),
componentsArgs: make(map[string]any), componentsArgs: make(map[string]any),
componentFilterFn: make(map[string][]func(*Handle, string) string), componentFilterFn: make(map[string][]func(*Handle, string, ...any) string),
} }
} }