From a1f36da904c4e7c5db9188cebf93b7cccb6e7bc9 Mon Sep 17 00:00:00 2001 From: xing Date: Mon, 27 Mar 2023 12:59:29 +0800 Subject: [PATCH] =?UTF-8?q?block=E7=89=88=20=E5=88=86=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/pkg/constraints/blocks/blocks.go | 10 ++ internal/theme/wp/components/block.go | 35 ++++ internal/theme/wp/components/block/block.go | 96 ++++++++++ .../theme/wp/components/block/block_test.go | 25 +++ .../theme/wp/components/block/category.go | 165 ++++++++++++++++++ .../theme/wp/components/widget/archive.go | 19 +- .../theme/wp/components/widget/category.go | 16 +- internal/theme/wp/components/widget/meta.go | 10 +- .../wp/components/widget/recentcomments.go | 21 ++- .../theme/wp/components/widget/recentposts.go | 20 ++- internal/theme/wp/components/widget/search.go | 10 +- 11 files changed, 400 insertions(+), 27 deletions(-) create mode 100644 internal/pkg/constraints/blocks/blocks.go create mode 100644 internal/theme/wp/components/block.go create mode 100644 internal/theme/wp/components/block/block.go create mode 100644 internal/theme/wp/components/block/block_test.go create mode 100644 internal/theme/wp/components/block/category.go diff --git a/internal/pkg/constraints/blocks/blocks.go b/internal/pkg/constraints/blocks/blocks.go new file mode 100644 index 0000000..7590880 --- /dev/null +++ b/internal/pkg/constraints/blocks/blocks.go @@ -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" +) diff --git a/internal/theme/wp/components/block.go b/internal/theme/wp/components/block.go new file mode 100644 index 0000000..389e412 --- /dev/null +++ b/internal/theme/wp/components/block.go @@ -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) (func() string, error){ + "core/categories": block.Category, +} + +func Block(id 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) + if err != nil { + continue + } + out = append(out, s()) + } + } + return strings.Join(out, "\n") + } +} diff --git a/internal/theme/wp/components/block/block.go b/internal/theme/wp/components/block/block.go new file mode 100644 index 0000000..d0ae863 --- /dev/null +++ b/internal/theme/wp/components/block/block.go @@ -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+)?(?\/)?-->`, 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 +} diff --git a/internal/theme/wp/components/block/block_test.go b/internal/theme/wp/components/block/block_test.go new file mode 100644 index 0000000..91bbb91 --- /dev/null +++ b/internal/theme/wp/components/block/block_test.go @@ -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: ``, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ParseBlock(tt.args.s) + }) + } +} diff --git a/internal/theme/wp/components/block/category.go b/internal/theme/wp/components/block/category.go new file mode 100644 index 0000000..9fb2287 --- /dev/null +++ b/internal/theme/wp/components/block/category.go @@ -0,0 +1,165 @@ +package block + +import ( + "encoding/json" + "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/constraints/blocks" + "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}": `
`, + "{$after_widget}": `
`, + "{$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) (func() string, error) { + counter := number.Counters[int]() + var con any + err := json.Unmarshal([]byte(blockParser.Attrs), &con) + if err != nil { + logs.ErrPrintln(err, "解析category attr错误", blockParser.Attrs) + return nil, err + } + 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) + } + + if maps.GetAnyAnyValWithDefaults(conf, false, "showEmpty") { + h.C.Set("showEmpty", true) + } + if maps.GetAnyAnyValWithDefaults(conf, false, "showOnlyTopLevel") { + h.C.Set("showOnlyTopLevel", true) + } + args := maps.FilterZeroMerge(categoryDefaultArgs(), wp.GetComponentsArgs[map[string]string](h, blocks.Categories, nil)) + 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}"], 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(``, 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(`
%s%s
`, attrs, ids, args["{$title}"], selects, strings.ReplaceAll(categoryDropdownScript, "{$id}", ids)) + return s.String() +} + +var categoryDropdownScript = ` + +` diff --git a/internal/theme/wp/components/widget/archive.go b/internal/theme/wp/components/widget/archive.go index 4aa94f9..52a5a2d 100644 --- a/internal/theme/wp/components/widget/archive.go +++ b/internal/theme/wp/components/widget/archive.go @@ -5,6 +5,7 @@ import ( "github.com/fthvgb1/wp-go/helper/maps" "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/pkg/cache" "github.com/fthvgb1/wp-go/internal/pkg/constraints/widgets" "github.com/fthvgb1/wp-go/internal/pkg/models" @@ -47,11 +48,19 @@ func archivesConfig() map[any]any { } func Archive(h *wp.Handle) string { - archiveArgs := archiveArgs() - archivesConfig := archivesConfig() - args := wp.GetComponentsArgs(h, widgets.Archive, archiveArgs) - args = maps.FilterZeroMerge(archiveArgs, args) - conf := wpconfig.GetPHPArrayVal("widget_archives", archivesConfig, int64(2)) + args := reload.GetAnyValBys("widget-archive-args", h, func(h *wp.Handle) map[string]string { + archiveArgs := archiveArgs() + args := wp.GetComponentsArgs(h, widgets.Archive, archiveArgs) + 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)) + return conf + }) + args["{$title}"] = str.Join(args["{$before_title}"], conf["title"].(string), args["{$after_title}"]) if id, ok := args["{$id}"]; ok && id != "" { args["{$before_widget}"] = strings.ReplaceAll(args["{$before_widget}"], "2", args["{$id}"]) diff --git a/internal/theme/wp/components/widget/category.go b/internal/theme/wp/components/widget/category.go index 4ba0c1c..821386a 100644 --- a/internal/theme/wp/components/widget/category.go +++ b/internal/theme/wp/components/widget/category.go @@ -6,6 +6,7 @@ import ( "github.com/fthvgb1/wp-go/helper/slice" str "github.com/fthvgb1/wp-go/helper/strings" "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/constraints" "github.com/fthvgb1/wp-go/internal/pkg/constraints/widgets" @@ -53,10 +54,17 @@ func categoryArgs() map[string]string { } func Category(h *wp.Handle) string { - args := wp.GetComponentsArgs(h, widgets.Categories, categoryArgs()) - args = maps.FilterZeroMerge(categoryArgs(), args) - conf := wpconfig.GetPHPArrayVal("widget_categories", categoryConfig(), int64(2)) - conf = maps.FilterZeroMerge(categoryConfig(), conf) + args := reload.GetAnyValBys("widget-category-args", h, func(h *wp.Handle) map[string]string { + args := wp.GetComponentsArgs(h, widgets.Categories, categoryArgs()) + 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 = maps.FilterZeroMerge(categoryConfig(), conf) + return conf + }) + args["{$title}"] = str.Join(args["{$before_title}"], conf["title"].(string), args["{$after_title}"]) t := categoryTemplate dropdown := conf["dropdown"].(int64) diff --git a/internal/theme/wp/components/widget/meta.go b/internal/theme/wp/components/widget/meta.go index 28719b1..5c0ed28 100644 --- a/internal/theme/wp/components/widget/meta.go +++ b/internal/theme/wp/components/widget/meta.go @@ -5,6 +5,7 @@ import ( "github.com/fthvgb1/wp-go/helper/maps" "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/pkg/constraints/widgets" "github.com/fthvgb1/wp-go/internal/theme/wp" "github.com/fthvgb1/wp-go/internal/wpconfig" @@ -33,9 +34,12 @@ func metaArgs() map[string]string { } func Meta(h *wp.Handle) string { - metaArgs := metaArgs() - args := wp.GetComponentsArgs(h, widgets.Meta, metaArgs) - args = maps.FilterZeroMerge(metaArgs, args) + args := reload.GetAnyValBys("widget-meta-args", h, func(h *wp.Handle) map[string]string { + metaArgs := metaArgs() + args := wp.GetComponentsArgs(h, widgets.Meta, metaArgs) + args = maps.FilterZeroMerge(metaArgs, args) + return args + }) args["{$title}"] = wpconfig.GetPHPArrayVal("widget_meta", "其它操作", int64(2), "title") if id, ok := args["{$id}"]; ok && id != "" { args["{$before_widget}"] = strings.ReplaceAll(args["{$before_widget}"], "2", args["{$id}"]) diff --git a/internal/theme/wp/components/widget/recentcomments.go b/internal/theme/wp/components/widget/recentcomments.go index 36d0f8d..2c4193c 100644 --- a/internal/theme/wp/components/widget/recentcomments.go +++ b/internal/theme/wp/components/widget/recentcomments.go @@ -5,6 +5,7 @@ import ( "github.com/fthvgb1/wp-go/helper/maps" "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/pkg/cache" "github.com/fthvgb1/wp-go/internal/pkg/constraints/widgets" "github.com/fthvgb1/wp-go/internal/pkg/models" @@ -46,12 +47,20 @@ var recentCommentsTemplate = `{$before_widget} ` func RecentComments(h *wp.Handle) string { - recentCommentsArgs := recentCommentsArgs() - recentCommentConf := recentCommentConf() - args := wp.GetComponentsArgs(h, widgets.RecentComments, recentCommentsArgs) - args = maps.FilterZeroMerge(recentCommentsArgs, args) - conf := wpconfig.GetPHPArrayVal("widget_recent-comments", recentCommentConf, int64(2)) - conf = maps.FilterZeroMerge(recentCommentConf, conf) + args := reload.GetAnyValBys("widget-recent-comment-args", h, func(h *wp.Handle) map[string]string { + commentsArgs := recentCommentsArgs() + args := wp.GetComponentsArgs(h, widgets.RecentComments, commentsArgs) + args = maps.FilterZeroMerge(commentsArgs, args) + return args + }) + + 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}"]) if id, ok := args["{$id}"]; ok && id != "" { args["{$before_widget}"] = strings.ReplaceAll(args["{$before_widget}"], "2", args["{$id}"]) diff --git a/internal/theme/wp/components/widget/recentposts.go b/internal/theme/wp/components/widget/recentposts.go index 937264b..5656aa6 100644 --- a/internal/theme/wp/components/widget/recentposts.go +++ b/internal/theme/wp/components/widget/recentposts.go @@ -5,6 +5,7 @@ import ( "github.com/fthvgb1/wp-go/helper/maps" "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/pkg/cache" "github.com/fthvgb1/wp-go/internal/pkg/constraints" "github.com/fthvgb1/wp-go/internal/pkg/constraints/widgets" @@ -47,12 +48,19 @@ func recentConf() map[any]any { } func RecentPosts(h *wp.Handle) string { - recentPostsArgs := recentPostsArgs() - recentConf := recentConf() - args := wp.GetComponentsArgs(h, widgets.RecentPosts, recentPostsArgs) - args = maps.FilterZeroMerge(recentPostsArgs, args) - conf := wpconfig.GetPHPArrayVal[map[any]any]("widget_recent-posts", recentConf, int64(2)) - conf = maps.FilterZeroMerge(recentConf, conf) + args := reload.GetAnyValBys("widget-recent-posts-args", h, func(h *wp.Handle) map[string]string { + recent := recentPostsArgs() + args := wp.GetComponentsArgs(h, widgets.RecentPosts, recent) + args = maps.FilterZeroMerge(recent, args) + return args + }) + 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 != "" { args["{$before_widget}"] = strings.ReplaceAll(args["{$before_widget}"], "2", args["{$id}"]) } diff --git a/internal/theme/wp/components/widget/search.go b/internal/theme/wp/components/widget/search.go index 9f79cad..be7d829 100644 --- a/internal/theme/wp/components/widget/search.go +++ b/internal/theme/wp/components/widget/search.go @@ -5,6 +5,7 @@ import ( "github.com/fthvgb1/wp-go/helper/maps" "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/pkg/constraints" "github.com/fthvgb1/wp-go/internal/pkg/constraints/widgets" "github.com/fthvgb1/wp-go/internal/theme/wp" @@ -49,9 +50,12 @@ func searchArgs() map[string]string { } func Search(h *wp.Handle) string { - searchArgs := searchArgs() - args := wp.GetComponentsArgs(h, widgets.Search, searchArgs) - args = maps.FilterZeroMerge(searchArgs, args) + args := reload.GetAnyValBys("widget-search-args", h, func(h *wp.Handle) map[string]string { + search := searchArgs() + args := wp.GetComponentsArgs(h, widgets.Search, search) + args = maps.FilterZeroMerge(search, args) + return args + }) if args["{$title}"] == "" { args["{$title}"] = wpconfig.GetPHPArrayVal("widget_search", "", int64(2), "title") }