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")