fix(html): preserve each path prefixes
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run

Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Virgil 2026-04-03 16:58:12 +00:00
parent ba384aeb12
commit 8dfce51659
2 changed files with 45 additions and 0 deletions

14
node.go
View file

@ -36,6 +36,8 @@ func renderNodeWithPath(n Node, ctx *Context, path string) string {
clone := *t
clone.path = path
return clone.Render(ctx)
case interface{ renderWithPath(*Context, string) string }:
return t.renderWithPath(ctx, path)
case *ifNode:
if t.cond(ctx) {
return renderNodeWithPath(t.node, ctx, path)
@ -352,3 +354,15 @@ func (n *eachNode[T]) Render(ctx *Context) string {
}
return b.String()
}
func (n *eachNode[T]) renderWithPath(ctx *Context, path string) string {
if n == nil || n.items == nil || n.fn == nil {
return ""
}
var b strings.Builder
for item := range n.items {
b.WriteString(renderNodeWithPath(n.fn(item), ctx, path))
}
return b.String()
}

View file

@ -3,6 +3,8 @@ package html
import (
"strings"
"testing"
"slices"
)
func TestNestedLayout_PathChain(t *testing.T) {
@ -78,6 +80,35 @@ func TestNestedLayout_ThroughSwitchWrapper(t *testing.T) {
}
}
func TestNestedLayout_ThroughEachWrapper(t *testing.T) {
ctx := NewContext()
items := []int{1, 2}
node := Each(items, func(i int) Node {
return NewLayout("C").C(Raw(strings.Repeat("x", i)))
})
got := NewLayout("C").C(node).Render(ctx)
if count := strings.Count(got, `data-block="C-0-C-0"`); count != 2 {
t.Fatalf("each wrapper should preserve nested block path twice, got %d in:\n%s", count, got)
}
}
func TestNestedLayout_ThroughEachSeqWrapper(t *testing.T) {
ctx := NewContext()
node := EachSeq(slices.Values([]string{"a", "b"}), func(s string) Node {
return NewLayout("C").C(Raw(s))
})
got := NewLayout("C").C(node).Render(ctx)
if count := strings.Count(got, `data-block="C-0-C-0"`); count != 2 {
t.Fatalf("eachseq wrapper should preserve nested block path twice, got %d in:\n%s", count, got)
}
}
func TestBlockID(t *testing.T) {
tests := []struct {
path string