diff --git a/node.go b/node.go index 8ae5395..4c7b225 100644 --- a/node.go +++ b/node.go @@ -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() +} diff --git a/path_test.go b/path_test.go index b41f75f..6c9cd50 100644 --- a/path_test.go +++ b/path_test.go @@ -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