Compare commits

...

2 Commits

Author SHA1 Message Date
ca94295eb7 其它操作 加隐藏登录插件 及优化完善 2023-03-17 00:45:04 +08:00
aaa1f3c937 tree 测试 2023-03-16 12:28:53 +08:00
18 changed files with 589 additions and 60 deletions

View File

@ -23,10 +23,20 @@
|-----|--------------------------------------------|
| 列表页 | 首页/搜索/归档/分类/标签/作者 分页列表 |
| 详情页 | 显示内容、评论并可以添加评论(转发的php处理需要配置php版的添加评论的url) |
| 侧边栏 | 目前固定 近期文章、近期评论、规档、分类、条目/评论feed |
| 侧边栏 | 目前支持旧版小工具的 近期文章、近期评论、规档、分类、其它操作 显示及设置 |
#### 后台设置支持程度
- 仪表盘
- 外观
- 小工具
- 搜索
- 规档
- 近期文章
- 近期评论
- 分类
- 其它操作
- 设置-
- 常规
- 站点标题
@ -55,7 +65,7 @@
| 列表页文章数据插件 | 整个程序表现的插件 |
|----------------------|--------------------------------------|
| passwordProject 密码保护 | enlighter 代码高亮(需要在后台安装enlighterjs插件) |
| digest 自动生成指定长度的摘要 | |
| digest 自动生成指定长度的摘要 | hiddenLogin 隐藏登录入口 |
#### 其它

View File

@ -14,6 +14,20 @@ func (n *Node[T, K]) GetChildren() []T {
})
}
func (n *Node[T, K]) Posterity() (r []T) {
n.posterity(&r)
return r
}
func (n *Node[T, K]) posterity(a *[]T) {
for _, n2 := range *n.Children {
*a = append(*a, n2.Data)
if len(*n2.Children) > 0 {
n2.posterity(a)
}
}
}
func (n *Node[T, K]) ChildrenByOrder(fn func(T, T) bool) []T {
a := slice.Map(*n.Children, func(t Node[T, K]) T {
return t.Data

398
helper/tree/tree_test.go Normal file
View File

@ -0,0 +1,398 @@
package tree
import (
"fmt"
"github.com/fthvgb1/wp-go/helper/slice"
"reflect"
"testing"
)
type xx struct {
id int
pid int
}
var ss []xx
func init() {
ss = []xx{
{1, 0},
{2, 0},
{3, 0},
{4, 1},
{5, 1},
{6, 2},
{7, 3},
{8, 4},
{9, 5},
{10, 2},
}
}
func ffn(x xx) (child, parent int) {
return x.id, x.pid
}
func TestAncestor(t *testing.T) {
type args[K comparable, T any] struct {
root map[K]*Node[T, K]
top K
child *Node[T, K]
}
type testCase[K comparable, T any] struct {
name string
args args[K, T]
want *Node[T, K]
}
r := Roots(ss, 0, ffn)
tests := []testCase[int, xx]{
{
name: "t1",
args: args[int, xx]{
root: r,
top: 0,
child: &Node[xx, int]{
Data: xx{9, 5},
Parent: 5,
},
},
want: &Node[xx, int]{
Data: xx{
id: 1,
pid: 0,
},
Children: &[]Node[xx, int]{
{
Data: xx{4, 1},
Children: &[]Node[xx, int]{
{
Data: xx{8, 4},
Parent: 4,
},
},
},
{
Data: xx{5, 1},
Children: &[]Node[xx, int]{
{
Data: xx{9, 5},
Parent: 5,
},
},
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := Ancestor(tt.args.root, tt.args.top, tt.args.child); !reflect.DeepEqual(*got, *tt.want) {
t.Errorf("Ancestor() = %v, want %v", got, tt.want)
}
})
}
}
func TestNode_ChildrenByOrder(t *testing.T) {
type args[T any] struct {
fn func(T, T) bool
}
type testCase[T any, K comparable] struct {
name string
n Node[T, K]
args args[T]
want []T
}
tests := []testCase[xx, int]{
{
name: "t1",
n: *root(ss, 0, ffn)[2],
args: args[xx]{
fn: func(x xx, x2 xx) bool {
return x.id < x2.id
},
},
want: []xx{{6, 2}, {10, 2}},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := tt.n.ChildrenByOrder(tt.args.fn); !reflect.DeepEqual(got, tt.want) {
t.Errorf("ChildrenByOrder() = %v, want %v", got, tt.want)
}
})
}
}
func TestNode_GetChildren(t *testing.T) {
type testCase[T any, K comparable] struct {
name string
n Node[T, K]
want []T
}
tests := []testCase[xx, int]{
{
name: "t1",
n: *root(ss, 0, ffn)[2],
want: []xx{{6, 2}, {10, 2}},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := tt.n.GetChildren(); !reflect.DeepEqual(got, tt.want) {
t.Errorf("GetChildren() = %v, want %v", got, tt.want)
}
})
}
}
func TestNode_Loop(t *testing.T) {
type args[T any] struct {
fn func(T, int)
}
type testCase[T any, K comparable] struct {
name string
n Node[T, K]
args args[T]
}
tests := []testCase[xx, int]{
{
name: "t1",
n: *Root(ss, 0, ffn),
args: args[xx]{
fn: func(x xx, i int) {
fmt.Println(x, i)
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.n.Loop(tt.args.fn)
})
}
}
func TestNode_OrderByLoop(t *testing.T) {
type args[T any] struct {
fn func(T, int)
orderBy func(T, T) bool
}
type testCase[T any, K comparable] struct {
name string
n Node[T, K]
args args[T]
}
tests := []testCase[xx, int]{
{
name: "",
n: *Root(ss, 0, ffn),
args: args[xx]{
fn: func(x xx, i int) {
fmt.Println(x)
},
orderBy: func(x xx, x2 xx) bool {
return x.id > x2.id
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.n.OrderByLoop(tt.args.fn, tt.args.orderBy)
})
}
}
func TestNode_Posterity(t *testing.T) {
type testCase[T any, K comparable] struct {
name string
n Node[T, K]
wantR []T
}
tests := []testCase[xx, int]{
{
name: "t1",
n: *Root(ss, 0, ffn),
wantR: ss,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotR := tt.n.Posterity()
fn := func(i, j xx) bool {
if i.id < j.id {
return true
}
if i.pid < j.pid {
return true
}
return false
}
slice.Sort(gotR, fn)
slice.Sort(tt.wantR, fn)
if !reflect.DeepEqual(gotR, tt.wantR) {
t.Errorf("Posterity() = %v, want %v", gotR, tt.wantR)
}
})
}
}
func TestNode_loop(t *testing.T) {
type args[T any] struct {
fn func(T, int)
deep int
}
type testCase[T any, K comparable] struct {
name string
n Node[T, K]
args args[T]
}
tests := []testCase[xx, int]{
{
name: "t1",
n: *Root(ss, 0, ffn),
args: args[xx]{fn: func(x xx, i int) {
fmt.Println(x)
}},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.n.loop(tt.args.fn, tt.args.deep)
})
}
}
func TestNode_orderByLoop(t *testing.T) {
type args[T any] struct {
fn func(T, int)
orderBy func(T, T) bool
deep int
}
type testCase[T any, K comparable] struct {
name string
n Node[T, K]
args args[T]
}
tests := []testCase[xx, int]{
{
name: "t1",
n: *Root(ss, 0, ffn),
args: args[xx]{fn: func(x xx, i int) {
fmt.Println(x)
}, orderBy: func(x xx, x2 xx) bool {
return x.id > x2.id
}},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.n.orderByLoop(tt.args.fn, tt.args.orderBy, tt.args.deep)
})
}
}
func TestNode_posterity(t *testing.T) {
type args[T any] struct {
a *[]T
}
type testCase[T any, K comparable] struct {
name string
n Node[T, K]
args args[T]
}
tests := []testCase[xx, int]{
{
name: "t1",
n: *Root(ss, 0, ffn),
args: args[xx]{a: new([]xx)},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.n.posterity(tt.args.a)
})
}
}
func TestRoot(t *testing.T) {
type args[T any, K comparable] struct {
a []T
top K
fn func(T) (child, parent K)
}
type testCase[T any, K comparable] struct {
name string
args args[T, K]
want *Node[T, K]
}
tests := []testCase[xx, int]{
{
name: "t1",
args: args[xx, int]{
a: ss,
top: 0,
fn: ffn,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := Root(tt.args.a, tt.args.top, tt.args.fn); !reflect.DeepEqual(got, tt.want) {
t.Errorf("Root() = %v, want %v", got, tt.want)
}
})
}
}
func TestRoots(t *testing.T) {
type args[T any, K comparable] struct {
a []T
top K
fn func(T) (child, parent K)
}
type testCase[T any, K comparable] struct {
name string
args args[T, K]
want map[K]*Node[T, K]
}
tests := []testCase[xx, int]{
{
name: "t1",
args: args[xx, int]{ss, 0, ffn},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := Roots(tt.args.a, tt.args.top, tt.args.fn); !reflect.DeepEqual(got, tt.want) {
t.Errorf("Roots() = %v, want %v", got, tt.want)
}
})
}
}
func Test_root(t *testing.T) {
type args[T any, K comparable] struct {
a []T
top K
fn func(T) (child, parent K)
}
type testCase[T any, K comparable] struct {
name string
args args[T, K]
want map[K]*Node[T, K]
}
tests := []testCase[xx, int]{
{
name: "t1",
args: args[xx, int]{ss, 0, ffn},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := root(tt.args.a, tt.args.top, tt.args.fn); !reflect.DeepEqual(got, tt.want) {
t.Errorf("root() = %v, want %v", got, tt.want)
}
})
}
}

View File

@ -1,9 +1,10 @@
package widgets
const (
SearchFormArgs = "SearchFormArgs"
RecentPostsArgs = "RecentPostsArgs"
RecentCommentsArgs = "RecentCommentsArgs"
ArchiveArgs = "ArchiveArgs"
Categories = "Categories"
Search = "search"
RecentPosts = "recent-posts"
RecentComments = "recent-comments"
Archive = "archives"
Categories = "categories"
Meta = "meta"
)

View File

@ -3,11 +3,13 @@ package wphandle
import (
"github.com/fthvgb1/wp-go/helper/maps"
"github.com/fthvgb1/wp-go/internal/plugins/wphandle/enlightjs"
"github.com/fthvgb1/wp-go/internal/plugins/wphandle/hiddenlogin"
"github.com/fthvgb1/wp-go/internal/theme/wp"
)
var plugins = wp.HandlePlugins{
"enlightjs": enlightjs.EnlighterJS,
"enlightjs": enlightjs.EnlighterJS,
"hiddenLogin": hiddenlogin.HiddenLogin,
}
func Plugins() wp.HandlePlugins {

View File

@ -0,0 +1,17 @@
package hiddenlogin
import (
str "github.com/fthvgb1/wp-go/helper/strings"
"github.com/fthvgb1/wp-go/internal/pkg/constraints/widgets"
"github.com/fthvgb1/wp-go/internal/theme/wp"
)
func HiddenLogin(h *wp.Handle) {
h.PushComponentFilterFn(widgets.Meta, func(h *wp.Handle, s string) string {
return str.Replace(s, map[string]string{
`<li><a href="/wp-login.php">登录</a></li>`: "",
`<li><a href="/feed">登录</a></li>`: "",
`<li><a href="/comments/feed">登录</a></li>`: "",
})
})
}

View File

@ -1,14 +1,5 @@
{{define "layout/sidebar" }}
<div id="widget-area" class="widget-area" role="complementary">
{{template "common/sidebarWidget" .}}
<aside id="meta-2" class="widget widget_meta"><h2 class="widget-title">其他操作</h2>
<nav aria-label="其他操作">
<ul>
<li><a href="/feed">条目feed</a></li>
<li><a href="/comments/feed">评论feed</a></li>
</ul>
</nav>
</aside>
</div>
{{end}}

View File

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

View File

@ -1,25 +1,3 @@
{{define "layout/sidebar" }}
{{template "common/sidebarWidget" .}}
<section id="categories-2" class="widget widget_categories">
<h2 class="widget-title">分类</h2>
<nav aria-label="分类">
<ul>
{{range $k,$v := .categories}}
<li class="cat-item cat-item-{{$v.Terms.TermId}}">
<a href="/p/category/{{$v.Name}}">{{$v.Name}}</a>
</li>
{{end}}
</ul>
</nav>
</section>
<section id="meta-2" class="widget widget_meta">
<h2 class="widget-title">其他操作</h2>
<nav aria-label="其他操作">
<ul>
<li><a href="/feed">条目feed</a></li>
<li><a href="/comments/feed">评论feed</a></li>
</ul>
</nav>
</section>
{{end}}

View File

@ -10,6 +10,7 @@ import (
"github.com/fthvgb1/wp-go/internal/cmd/reload"
"github.com/fthvgb1/wp-go/internal/pkg/config"
"github.com/fthvgb1/wp-go/internal/pkg/constraints"
"github.com/fthvgb1/wp-go/internal/pkg/constraints/widgets"
"github.com/fthvgb1/wp-go/internal/pkg/logs"
"github.com/fthvgb1/wp-go/internal/pkg/models"
"github.com/fthvgb1/wp-go/internal/plugins"
@ -61,9 +62,29 @@ func ready(next wp.HandleFn[*wp.Handle], h *wp.Handle) {
pushScripts(h)
h.SetData("HeaderImage", getHeaderImage(h))
h.SetData("scene", h.Scene())
for _, s := range []string{widgets.Meta, widgets.Categories, widgets.Archive, widgets.Search, widgets.RecentComments, widgets.RecentPosts} {
ss := strings.ReplaceAll(s, "-", "_")
if s == widgets.RecentPosts {
ss = "recent_entries"
}
wp.SetComponentsArgsForMap(h, s, "{$before_widget}", fmt.Sprintf(`<section id="%s-2" class="widget widget_%s">`, s, ss))
wp.SetComponentsArgsForMap(h, s, "{$after_widget}", "</section>")
}
wp.SetComponentsArgsForMap(h, widgets.Search, "{$form}", searchForm)
next(h)
}
var searchForm = `<form role="search" method="get" class="search-form" action="/">
<label for="search-form-1">
<span class="screen-reader-text">{$label}</span>
</label>
<input type="search" id="search-form-1" class="search-field" placeholder="{$placeholder}…" value="{$value}" name="s">
<button type="submit" class="search-submit">
<svg class="icon icon-search" aria-hidden="true" role="img"> <use href="#icon-search" xlink:href="#icon-search"></use> </svg>
<span class="screen-reader-text">{$button}</span>
</button>
</form>`
func dispatch(next wp.HandleFn[*wp.Handle], h *wp.Handle) {
switch h.Scene() {
case constraints.Detail:

View File

@ -36,6 +36,9 @@ func (h *Handle) BodyClass(class ...string) string {
case constraints.Category, constraints.Tag:
class = append(class, "archive", "category")
cat := h.Index.Param.Category
if cat == "" {
break
}
_, cate := slice.SearchFirst(cache.CategoriesTags(h.C, h.scene), func(my models.TermsMy) bool {
return my.Name == cat
})

View File

@ -49,17 +49,20 @@ var archiveTemplate = `{$before_widget}
`
func Archive(h *wp.Handle) string {
args := wp.GetComponentsArgs(h, widgets.ArchiveArgs, archiveArgs.Load())
args := wp.GetComponentsArgs(h, widgets.Archive, archiveArgs.Load())
args = maps.FilterZeroMerge(archiveArgs.Load(), args)
conf := wpconfig.GetPHPArrayVal("widget_archives", archivesConfig.Load(), int64(2))
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}"])
}
s := archiveTemplate
if int64(1) == conf["dropdown"].(int64) {
s = strings.ReplaceAll(s, "{$html}", archiveDropDown(h, conf, args, cache.Archives(h.C)))
} else {
s = strings.ReplaceAll(s, "{$html}", archiveUl(h, conf, args, cache.Archives(h.C)))
}
return h.ComponentFilterFnHook(widgets.ArchiveArgs, str.Replace(s, args))
return h.ComponentFilterFnHook(widgets.Archive, str.Replace(s, args))
}
var dropdownScript = `

View File

@ -36,7 +36,7 @@ var categoryConfig = func() safety.Var[map[any]any] {
"{$class}": "postform",
"{$show_option_none}": "选择分类",
"{$name}": "cat",
"{$id}": "cat",
"{$selectId}": "cat",
"{$required}": "",
"{$nav}": "",
"{$navCloser}": "",
@ -64,6 +64,9 @@ func Category(h *wp.Handle) string {
args["{$title}"] = str.Join(args["{$before_title}"], conf["title"].(string), args["{$after_title}"])
t := categoryTemplate
dropdown := conf["dropdown"].(int64)
if id, ok := args["{$id}"]; ok && id != "" {
args["{$before_widget}"] = strings.ReplaceAll(args["{$before_widget}"], "2", args["{$id}"])
}
categories := cache.CategoriesTags(h.C, constraints.Category)
if dropdown == 1 {
t = strings.ReplaceAll(t, "{$html}", categoryDropdown(h, args, conf, categories))
@ -71,7 +74,7 @@ func Category(h *wp.Handle) string {
} else {
t = strings.ReplaceAll(t, "{$html}", categoryUL(h, args, conf, categories))
}
return str.Replace(t, args)
return h.ComponentFilterFnHook(widgets.Categories, str.Replace(t, args))
}
func categoryUL(h *wp.Handle, args map[string]string, conf map[any]any, categories []models.TermsMy) string {
@ -173,10 +176,10 @@ func categoryDropdown(h *wp.Handle, args map[string]string, conf map[any]any, ca
s.WriteString(`<form action="/" method="get">
`)
s.Sprintf(` <label class="screen-reader-text" for="%s">%s</label>
`, args["{$id}"], args["{$title}"])
`, args["{$selectId}"], args["{$title}"])
if len(categories) > 0 {
s.Sprintf(` <select %s name="%s" id="%s" class="%s">
`, args["{$required}"], args["{$name}"], args["{$id}"], args["{$class}"])
`, args["{$required}"], args["{$name}"], args["{$selectId}"], args["{$class}"])
s.Sprintf(` <option value="%[1]s">%[1]s</option>
`, args["{$show_option_none}"])
currentCategory := ""
@ -218,7 +221,7 @@ func categoryDropdown(h *wp.Handle, args map[string]string, conf map[any]any, ca
}
s.Sprintf(`<script%s>
`, attr)
s.Sprintf(categoryDropdownJs, args["{$id}"])
s.Sprintf(categoryDropdownJs, args["{$selectId}"])
s.WriteString("</script>\n")
return s.String()
}

View File

@ -0,0 +1,64 @@
package widget
import (
"fmt"
"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/pkg/constraints/widgets"
"github.com/fthvgb1/wp-go/internal/theme/wp"
"github.com/fthvgb1/wp-go/internal/wpconfig"
"github.com/fthvgb1/wp-go/safety"
"strings"
)
var metaTemplate = `{$before_widget}
{$h2title}
{$nav}
<ul>
{$li}
</ul>
{$navCloser}
{$after_widget}`
var metaArgs = func() safety.Var[map[string]string] {
v := safety.Var[map[string]string]{}
v.Store(map[string]string{
"{$before_widget}": `<aside id="meta-2" class="widget widget_meta">`,
"{$after_widget}": `</aside>`,
"{$aria_label}": "",
"{$title}": "",
"": "",
"{$before_title}": `<h2 class="widget-title">`,
"{$after_title}": `</h2>`,
})
return v
}()
func Meta(h *wp.Handle) string {
args := wp.GetComponentsArgs(h, widgets.Meta, metaArgs.Load())
args = maps.FilterZeroMerge(metaArgs.Load(), 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}"])
}
if args["{$title}"] == "" {
args["{$title}"] = "其他操作"
}
if args["{$title}"] != "" {
args["{$h2title}"] = str.Join(args["{$before_title}"], args["{$title}"], args["{$after_title}"])
}
if slice.IsContained(h.CommonThemeMods().ThemeSupport.HTML5, "navigation-widgets") {
args["{$nav}"] = fmt.Sprintf(`<nav aria-label="%s">`, args["{$title}"])
args["{$navCloser}"] = "</nav>"
}
ss := str.NewBuilder()
if str.ToInteger(wpconfig.GetOption("users_can_register"), 0) > 0 {
ss.Sprintf(`<li><a href="/wp-login.php?action=register">注册</li>`)
}
ss.Sprintf(`<li><a href="%s">登录</a></li>`, "/wp-login.php")
ss.Sprintf(`<li><a href="%s">条目feed</a></li>`, "/feed")
ss.Sprintf(`<li><a href="%s">评论feed</a></li>`, "/comments/feed")
s := strings.ReplaceAll(metaTemplate, "{$li}", ss.String())
return h.ComponentFilterFnHook(widgets.Meta, str.Replace(s, args))
}

View File

@ -48,11 +48,14 @@ var recentCommentsTemplate = `{$before_widget}
`
func RecentComments(h *wp.Handle) string {
args := wp.GetComponentsArgs(h, widgets.RecentCommentsArgs, recentCommentsArgs.Load())
args := wp.GetComponentsArgs(h, widgets.RecentComments, recentCommentsArgs.Load())
args = maps.FilterZeroMerge(recentCommentsArgs.Load(), args)
conf := wpconfig.GetPHPArrayVal("widget_recent-comments", recentCommentConf.Load(), int64(2))
conf = maps.FilterZeroMerge(recentCommentConf.Load(), 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}"])
}
if slice.IsContained(h.CommonThemeMods().ThemeSupport.HTML5, "navigation-widgets") {
args["{$nav}"] = fmt.Sprintf(`<nav aria-label="%s">`, conf["title"])
args["{$navCloser}"] = "</nav>"
@ -65,5 +68,5 @@ func RecentComments(h *wp.Handle) string {
</li>`, t.CommentAuthor, t.CommentId, t.CommentPostId, t.PostTitle)
})
s := strings.ReplaceAll(recentCommentsTemplate, "{$li}", strings.Join(comments, "\n"))
return h.ComponentFilterFnHook(widgets.RecentCommentsArgs, str.Replace(s, args))
return h.ComponentFilterFnHook(widgets.RecentComments, str.Replace(s, args))
}

View File

@ -50,10 +50,13 @@ var recentConf = func() safety.Var[map[any]any] {
}()
func RecentPosts(h *wp.Handle) string {
args := wp.GetComponentsArgs(h, widgets.RecentPostsArgs, recentPostsArgs.Load())
args := wp.GetComponentsArgs(h, widgets.RecentPosts, recentPostsArgs.Load())
args = maps.FilterZeroMerge(recentPostsArgs.Load(), args)
conf := wpconfig.GetPHPArrayVal[map[any]any]("widget_recent-posts", recentConf.Load(), int64(2))
conf = maps.FilterZeroMerge(recentConf.Load(), conf)
if id, ok := args["{$id}"]; ok && id != "" {
args["{$before_widget}"] = strings.ReplaceAll(args["{$before_widget}"], "2", args["{$id}"])
}
args["{$title}"] = str.Join(args["{$before_title}"], conf["title"].(string), args["{$after_title}"])
if slice.IsContained(h.CommonThemeMods().ThemeSupport.HTML5, "navigation-widgets") {
args["{$nav}"] = fmt.Sprintf(`<nav aria-label="%s">`, conf["title"])
@ -79,5 +82,5 @@ func RecentPosts(h *wp.Handle) string {
</li>`, t.Id, ariaCurrent, t.PostTitle, date)
})
s := strings.ReplaceAll(recentPostsTemplate, "{$li}", strings.Join(posts, "\n"))
return h.ComponentFilterFnHook(widgets.RecentPostsArgs, str.Replace(s, args))
return h.ComponentFilterFnHook(widgets.RecentPosts, str.Replace(s, args))
}

View File

@ -21,12 +21,14 @@ var searchTemplate = `{$before_widget}
var searchArgs = func() safety.Var[map[string]string] {
v := safety.Var[map[string]string]{}
v.Store(map[string]string{
"{$id}": "2",
"{$before_widget}": `<aside id="search-2" class="widget widget_search">`,
"{$after_widget}": `</aside>`,
"{$aria_label}": "",
"{$title}": "",
"{$before_title}": `<h2 class="widget-title">`,
"{$after_title}": `</h2>`,
"{$form}": "",
"{$button}": "搜索",
"{$placeholder}": "搜索&hellip;",
"{$label}": "搜索:",
@ -50,11 +52,14 @@ var xmlSearchForm = `<form role="search" {$aria_label} method="get" id="searchfo
</form>`
func SearchForm(h *wp.Handle) string {
args := wp.GetComponentsArgs(h, widgets.SearchFormArgs, searchArgs.Load())
args := wp.GetComponentsArgs(h, widgets.Search, searchArgs.Load())
args = maps.FilterZeroMerge(searchArgs.Load(), args)
if args["{$title}"] == "" {
args["{$title}"] = wpconfig.GetPHPArrayVal("widget_search", "", int64(2), "title")
}
if id, ok := args["{$id}"]; ok && id != "" {
args["{$before_widget}"] = strings.ReplaceAll(args["{$before_widget}"], "2", args["{$id}"])
}
if args["{$title}"] != "" {
args["{$title}"] = str.Join(args["{$before_title}"], args["{$title}"], args["{$after_title}"])
}
@ -63,9 +68,14 @@ func SearchForm(h *wp.Handle) string {
args["{$value}"] = html.SpecialChars(h.Index.Param.Search)
}
form := html5SearchForm
if !slice.IsContained(h.CommonThemeMods().ThemeSupport.HTML5, "search-form") {
if args["{$form}"] != "" {
form = args["{$form}"]
delete(args, "{$form}")
}
if !slice.IsContained(h.CommonThemeMods().ThemeSupport.HTML5, "navigation-widgets") {
form = xmlSearchForm
}
s := strings.ReplaceAll(searchTemplate, "{$form}", form)
return h.ComponentFilterFnHook(widgets.SearchFormArgs, str.Replace(s, args))
return h.ComponentFilterFnHook(widgets.Search, str.Replace(s, args))
}

View File

@ -7,22 +7,30 @@ import (
"github.com/fthvgb1/wp-go/internal/theme/wp"
"github.com/fthvgb1/wp-go/internal/theme/wp/components/widget"
"github.com/fthvgb1/wp-go/internal/wpconfig"
"strings"
)
var widgets = map[string]func(*wp.Handle) string{
"search-2": widget.SearchForm,
"recent-posts-2": widget.RecentPosts,
"recent-comments-2": widget.RecentComments,
"archives-2": widget.Archive,
"categories-2": widget.Category,
"search": widget.SearchForm,
"recent-posts": widget.RecentPosts,
"recent-comments": widget.RecentComments,
"archives": widget.Archive,
"categories": widget.Category,
"meta": widget.Meta,
}
func WidgetArea(h *wp.Handle) {
v := wpconfig.GetPHPArrayVal("sidebars_widgets", []any{}, "sidebar-1")
sidebar := slice.FilterAndMap(v, func(t any) (func(*wp.Handle) string, bool) {
vv := t.(string)
fn, ok := widgets[vv]
ss := strings.Split(vv, "-")
id := ss[len(ss)-1]
name := strings.Join(ss[0:len(ss)-1], "-")
fn, ok := widgets[name]
if ok {
if id != "2" {
wp.SetComponentsArgsForMap(h, name, "{$id}", id)
}
return fn, true
}
return nil, false