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
|
package pongo2
import (
"bytes"
)
type tagWithNode struct {
with_pairs map[string]IEvaluator
wrapper *NodeWrapper
}
func (node *tagWithNode) Execute(ctx *ExecutionContext, buffer *bytes.Buffer) *Error {
//new context for block
withctx := NewChildExecutionContext(ctx)
// Put all custom with-pairs into the context
for key, value := range node.with_pairs {
val, err := value.Evaluate(ctx)
if err != nil {
return err
}
withctx.Private[key] = val
}
return node.wrapper.Execute(withctx, buffer)
}
func tagWithParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) {
with_node := &tagWithNode{
with_pairs: make(map[string]IEvaluator),
}
if arguments.Count() == 0 {
return nil, arguments.Error("Tag 'with' requires at least one argument.", nil)
}
wrapper, endargs, err := doc.WrapUntilTag("endwith")
if err != nil {
return nil, err
}
with_node.wrapper = wrapper
if endargs.Count() > 0 {
return nil, endargs.Error("Arguments not allowed here.", nil)
}
// Scan through all arguments to see which style the user uses (old or new style).
// If we find any "as" keyword we will enforce old style; otherwise we will use new style.
old_style := false // by default we're using the new_style
for i := 0; i < arguments.Count(); i++ {
if arguments.PeekN(i, TokenKeyword, "as") != nil {
old_style = true
break
}
}
for arguments.Remaining() > 0 {
if old_style {
value_expr, err := arguments.ParseExpression()
if err != nil {
return nil, err
}
if arguments.Match(TokenKeyword, "as") == nil {
return nil, arguments.Error("Expected 'as' keyword.", nil)
}
key_token := arguments.MatchType(TokenIdentifier)
if key_token == nil {
return nil, arguments.Error("Expected an identifier", nil)
}
with_node.with_pairs[key_token.Val] = value_expr
} else {
key_token := arguments.MatchType(TokenIdentifier)
if key_token == nil {
return nil, arguments.Error("Expected an identifier", nil)
}
if arguments.Match(TokenSymbol, "=") == nil {
return nil, arguments.Error("Expected '='.", nil)
}
value_expr, err := arguments.ParseExpression()
if err != nil {
return nil, err
}
with_node.with_pairs[key_token.Val] = value_expr
}
}
return with_node, nil
}
func init() {
RegisterTag("with", tagWithParser)
}
|