Raw
 1package web
 2
 3import (
 4	"errors"
 5	"html/template"
 6	"text/template/parse"
 7
 8	"tug/internal/transport/web/text"
 9)
10
11func walkPipes(n parse.Node, f func(*parse.PipeNode)) {
12	switch n := n.(type) {
13	case *parse.ListNode:
14		if n == nil {
15			return
16		}
17		for _, c := range n.Nodes {
18			walkPipes(c, f)
19		}
20	case *parse.ActionNode:
21		f(n.Pipe)
22	case *parse.IfNode:
23		f(n.Pipe)
24		walkPipes(n.List, f)
25		walkPipes(n.ElseList, f)
26	case *parse.RangeNode:
27		f(n.Pipe)
28		walkPipes(n.List, f)
29		walkPipes(n.ElseList, f)
30	case *parse.WithNode:
31		f(n.Pipe)
32		walkPipes(n.List, f)
33		walkPipes(n.ElseList, f)
34	case *parse.TemplateNode:
35		f(n.Pipe)
36	}
37}
38
39func templateKeys(tpl *template.Template) []text.Key {
40	var keys []text.Key
41	for _, tt := range tpl.Templates() {
42		if tt.Tree == nil {
43			continue
44		}
45		walkPipes(tt.Tree.Root, func(p *parse.PipeNode) {
46			if p == nil {
47				return
48			}
49			for _, c := range p.Cmds {
50				if len(c.Args) < 2 {
51					continue
52				}
53				id, ok := c.Args[0].(*parse.IdentifierNode)
54				if !ok || (id.Ident != "t" && id.Ident != "tr" && id.Ident != "trt") {
55					continue
56				}
57				if s, ok := c.Args[1].(*parse.StringNode); ok {
58					keys = append(keys, text.Key(s.Text))
59				}
60			}
61		})
62	}
63	return keys
64}
65
66func checkKeys(tpl *template.Template) error {
67	for _, k := range templateKeys(tpl) {
68		if _, err := lookup(k); err != nil {
69			return err
70		}
71	}
72	return nil
73}
74
75var errNoPage = errors.New("no such page template")