1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
package tags
import (
"fmt"
"strings"
"dove/utils/collections"
"dove/utils/errors"
"dove/utils/urls"
"github.com/flosch/pongo2/v6"
)
type UrlNode struct {
RouteName string
Params collections.Record[string, pongo2.IEvaluator]
VariableName string
}
func url(document *pongo2.Parser, start *pongo2.Token, arguments *pongo2.Parser) (pongo2.INodeTag, *pongo2.Error) {
routeNameToken := arguments.MatchType(pongo2.TokenString)
if routeNameToken == nil {
return nil, arguments.Error(ExpectedRouteName, nil)
}
params := make(collections.Record[string, pongo2.IEvaluator])
var variableName string
for arguments.Remaining() > 0 {
if arguments.Match(pongo2.TokenKeyword, "as") != nil {
nameToken := arguments.MatchType(pongo2.TokenIdentifier)
if nameToken == nil {
return nil, arguments.Error(ExpectedVariableName, nil)
}
variableName = nameToken.Val
break
}
keyToken := arguments.MatchType(pongo2.TokenIdentifier)
if keyToken == nil {
return nil, arguments.Error(ExpectedParamKey, nil)
}
if arguments.Match(pongo2.TokenSymbol, "=") == nil {
return nil, arguments.Error(ExpectedEquals, nil)
}
valueExpression, parseError := arguments.ParseExpression()
if parseError != nil {
return nil, parseError
}
params[keyToken.Val] = valueExpression
}
return &UrlNode{
RouteName: routeNameToken.Val,
Params: params,
VariableName: variableName,
}, nil
}
func (self *UrlNode) Execute(executionContext *pongo2.ExecutionContext, writer pongo2.TemplateWriter) *pongo2.Error {
path, exists := urls.GetFullPath(self.RouteName)
if !exists {
return &pongo2.Error{
Sender: "tag:url",
OrigError: errors.Error(RouteNotFound, self.RouteName),
}
}
for key, expression := range self.Params {
evaluatedValue, evaluationError := expression.Evaluate(executionContext)
if evaluationError != nil {
return evaluationError
}
placeholder := fmt.Sprintf(":%s", key)
replacement := fmt.Sprintf("%v", evaluatedValue.Interface())
path = strings.ReplaceAll(path, placeholder, replacement)
}
if self.VariableName != "" {
executionContext.Public[self.VariableName] = path
return nil
}
_, writeError := writer.WriteString(path)
if writeError != nil {
return &pongo2.Error{
Sender: "tag:url",
OrigError: errors.Error(TemplateWriteFailed),
}
}
return nil
}
|