diff --git a/helper/tree/tree.go b/helper/tree/tree.go
index 66c2ff7..4f48603 100644
--- a/helper/tree/tree.go
+++ b/helper/tree/tree.go
@@ -51,6 +51,15 @@ func (n *Node[T, K]) OrderByLoop(fn func(T, int), orderBy func(T, T) bool) {
}
func Root[T any, K comparable](a []T, top K, fn func(T) (child, parent K)) *Node[T, K] {
+ m := root(a, top, fn)
+ return m[top]
+}
+
+func Roots[T any, K comparable](a []T, top K, fn func(T) (child, parent K)) map[K]*Node[T, K] {
+ return root(a, top, fn)
+}
+
+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[top] = &Node[T, K]{Children: new([]Node[T, K])}
for _, t := range a {
@@ -64,5 +73,19 @@ func Root[T any, K comparable](a []T, top K, fn func(T) (child, parent K)) *Node
}
*parent.Children = append(*parent.Children, node)
}
- return m[top]
+ return m
+}
+
+func Ancestor[T any, K comparable](root map[K]*Node[T, K], top K, child *Node[T, K]) *Node[T, K] {
+ a := child
+ for {
+ if a.Parent == top {
+ return a
+ }
+ aa, ok := root[a.Parent]
+ if !ok {
+ return a
+ }
+ a = aa
+ }
}
diff --git a/internal/theme/wp/components/widget/category.go b/internal/theme/wp/components/widget/category.go
index f71b75c..28e4a2f 100644
--- a/internal/theme/wp/components/widget/category.go
+++ b/internal/theme/wp/components/widget/category.go
@@ -82,18 +82,77 @@ func categoryUL(h *wp.Handle, args map[string]string, conf map[any]any, categori
s := str.NewBuilder()
s.WriteString("
\n")
isCount := conf["count"].(int64)
- for _, category := range categories {
+ if conf["hierarchical"].(int64) == 0 {
+ for _, category := range categories {
+ count := ""
+ if isCount != 0 {
+ count = fmt.Sprintf("(%d)", category.Count)
+ }
+ s.Sprintf(` -
+ %s %s
+
+`, category.Terms.TermId, category.Name, category.Name, count)
+ }
+ } else {
+
+ m := tree.Roots(categories, 0, func(cate models.TermsMy) (child, parent uint64) {
+ return cate.TermTaxonomyId, cate.Parent
+ })
+ cate := &tree.Node[models.TermsMy, uint64]{Data: models.TermsMy{}}
+ if h.Scene() == constraints.Category {
+ cat := h.C.Param("category")
+ i, ca := slice.SearchFirst(categories, func(my models.TermsMy) bool {
+ return cat == my.Name
+ })
+ if i > 0 {
+ cate = m[ca.TermTaxonomyId]
+ }
+ }
+
+ r := m[0]
+ categoryLi(r, cate, tree.Ancestor(m, 0, cate), isCount, s)
+ }
+
+ s.WriteString("
")
+ return s.String()
+}
+
+func categoryLi(root *tree.Node[models.TermsMy, uint64], cate, roots *tree.Node[models.TermsMy, uint64], isCount int64, s *str.Builder) {
+ for _, child := range *root.Children {
+ category := child.Data
count := ""
if isCount != 0 {
count = fmt.Sprintf("(%d)", category.Count)
}
- s.Sprintf(`
- %s %s
+ var class []string
+
+ if len(*child.Children) > 0 && cate.Data.TermTaxonomyId > 0 {
+ if category.TermTaxonomyId == cate.Parent {
+ class = append(class, "current-cat-parent")
+ }
+
+ if cate.Parent > 0 && category.TermTaxonomyId == roots.Data.TermTaxonomyId {
+ class = append(class, "current-cat-ancestor")
+ }
+ }
+ aria := ""
+ if category.TermTaxonomyId == cate.Data.TermTaxonomyId {
+ class = append(class, "current-cat")
+ aria = `aria-current="page"`
+ }
+ s.Sprintf(`
+ %s %s
-`, category.Terms.TermId, category.Name, category.Name, count)
+`, category.Terms.TermId, strings.Join(class, " "), aria, category.Name, category.Name, count)
+
+ if len(*child.Children) > 0 {
+ s.WriteString(`
+`)
+ categoryLi(&child, cate, roots, isCount, s)
+ s.WriteString(`
`)
+ }
}
- s.WriteString("")
- return s.String()
+
}
var categoryDropdownJs = `/*