]> git.earlybird.gay Git - today/commitdiff
add range template blocks
authorearly <me@earlybird.gay>
Tue, 31 Dec 2024 05:57:31 +0000 (22:57 -0700)
committerearly <me@earlybird.gay>
Tue, 31 Dec 2024 05:57:31 +0000 (22:57 -0700)
web/htmlt/parse/parse.go
web/htmlt/parse/parse_test.go

index 6c1e630206b41d75a82221a7e29c1a0259684df5..cb0f682f4e9a1373c1913d271a00dcdb918923e0 100644 (file)
@@ -150,6 +150,8 @@ readTemplate:
                                        p.tokens.discardUntil(TEMPLATE_CLOSE)
                                }
                                return &TemplateElse{}, nil
+                       case "range":
+                               return p.templateRangeNode(callback)
                        case "with":
                                return p.templateWithNode(callback)
                        case "end":
@@ -294,6 +296,46 @@ func (p *parser) templateWithNode(callback contentFunc) (*TemplateWith, error) {
        return node, nil
 }
 
+type TemplateRange struct {
+       Expression string
+       Content    []any
+}
+
+func (node *TemplateRange) String() string {
+       return fmt.Sprintf("{{ range %s }}%s{{ end }}", node.Expression, fmt.Sprint(node.Content...))
+}
+
+func (p *parser) templateRangeNode(callback contentFunc) (*TemplateRange, error) {
+       p.debug.Println("reading template range")
+       node := new(TemplateRange)
+       for tok := range p.tokens.until(TEMPLATE_CLOSE) {
+               switch tok.Type {
+               case TEXT, WHITESPACE:
+                       node.Expression += tok.Literal
+               }
+       }
+       node.Expression = strings.TrimSpace(node.Expression)
+
+       acc := make([]any, 0)
+       for {
+               then, err := callback(TEMPLATE_OPEN)
+               if err != nil {
+                       return nil, err
+               }
+               if len(then) == 0 {
+                       break
+               }
+               acc = append(acc, then...)
+               last := acc[len(acc)-1]
+               if _, ok := last.(*TemplateEnd); ok {
+                       node.Content = acc[:len(acc)-1]
+                       break
+               }
+       }
+       p.debug.Printf("read template range %s", node)
+       return node, nil
+}
+
 var voidElems = []string{
        "area", "base", "br", "col",
        "embed", "hr", "img", "input",
index 44c68fae539186cf6cef5c0eac3e3c7b874cb828..c35982692be67657fde61f747b6d36ae164907c6 100644 (file)
@@ -30,6 +30,8 @@ func TestParseBasic(t *testing.T) {
                {name: "if-elif-else-nested", input: "{{ if .m1 }}{{ .m1 }}{{ else if m2 }}{{ .m2 }}{{ else }}{{ .m3 }}{{ end }}"},
                {name: "with", input: "{{ with .message }}hello{{ end }}"},
                {name: "with-nested", input: "{{ with .message }}{{ . }}{{ end }}"},
+               {name: "range", input: "{{ range .messages }}hellp{{ end }}"},
+               {name: "range-nested", input: "{{ range .messages }}{{ . }}{{ end }}"},
        }
        /*
                testStrings := map[string]string{