1
0
mirror of https://github.com/danog/liquid.git synced 2024-11-27 02:34:39 +01:00

Add RenderContext.ParseTagArgs

This commit is contained in:
Oliver Steele 2017-06-30 17:33:36 -04:00
parent af95c44a25
commit 7c48138dad
8 changed files with 45 additions and 25 deletions

View File

@ -11,7 +11,7 @@ type Chunk struct {
Type ChunkType
SourceInfo SourceInfo
Name string // Name is the tag name of a tag Chunk. E.g. the tag name of "{% if 1 %}" is "if".
Parameters string // Parameters is the tag arguments of a tag Chunk. E.g. the tag arguments of "{% if 1 %}" is "1".
Args string // Parameters is the tag arguments of a tag Chunk. E.g. the tag arguments of "{% if 1 %}" is "1".
Source string // Source is the entirety of the chunk, including the "{{", "{%", etc. markers.
}
@ -38,9 +38,9 @@ func (c Chunk) String() string {
case TextChunkType:
return fmt.Sprintf("%s{%#v}", c.Type, c.Source)
case TagChunkType:
return fmt.Sprintf("%s{Tag:%#v, Args:%#v}", c.Type, c.Name, c.Parameters)
return fmt.Sprintf("%s{Tag:%#v, Args:%#v}", c.Type, c.Name, c.Args)
case ObjChunkType:
return fmt.Sprintf("%s{%#v}", c.Type, c.Parameters)
return fmt.Sprintf("%s{%#v}", c.Type, c.Args)
default:
return fmt.Sprintf("%s{%#v}", c.Type, c.Source)
}

View File

@ -21,7 +21,7 @@ func (c Chunk) MarshalYAML() (interface{}, error) {
case TextChunkType:
return map[string]interface{}{"text": c.Source}, nil
case TagChunkType:
return map[string]interface{}{"tag": c.Name, "args": c.Parameters}, nil
return map[string]interface{}{"tag": c.Name, "args": c.Args}, nil
case ObjChunkType:
return map[string]interface{}{"obj": c.Name}, nil
default:
@ -33,7 +33,7 @@ func (c Chunk) MarshalYAML() (interface{}, error) {
func (n ASTControlTag) MarshalYAML() (interface{}, error) {
return map[string]map[string]interface{}{
n.cd.name: {
"args": n.Parameters,
"args": n.Args,
"body": n.Body,
"branches": n.Branches,
}}, nil

View File

@ -45,7 +45,7 @@ func (s Settings) parseChunks(chunks []Chunk) (ASTNode, error) {
rawTag.slices = append(rawTag.slices, c.Source)
}
case c.Type == ObjChunkType:
expr, err := expressions.Parse(c.Parameters)
expr, err := expressions.Parse(c.Args)
if err != nil {
return nil, err
}
@ -82,7 +82,7 @@ func (s Settings) parseChunks(chunks []Chunk) (ASTNode, error) {
ccd, ccn, ap = f.cd, f.cn, f.ap
}
} else if td, ok := s.FindTagDefinition(c.Name); ok {
f, err := td(c.Parameters)
f, err := td(c.Args)
if err != nil {
return nil, err
}

View File

@ -4,6 +4,7 @@ import (
"bytes"
"fmt"
"io"
"strings"
"github.com/osteele/liquid/expressions"
)
@ -16,10 +17,10 @@ type RenderContext interface {
Evaluate(expr expressions.Expression) (interface{}, error)
EvaluateString(source string) (interface{}, error)
EvaluateStatement(tag, source string) (interface{}, error)
InnerString() (string, error)
ParseTagArgs() (string, error)
RenderChild(io.Writer, *ASTControlTag) error
RenderChildren(io.Writer) error
// RenderTemplate(io.Writer, filename string) (string, error)
InnerString() (string, error)
}
type renderContext struct {
@ -82,10 +83,6 @@ func (c renderContext) RenderChildren(w io.Writer) error {
return c.ctx.RenderASTSequence(w, c.cn.Body)
}
// func (c renderContext) RenderTemplate(w io.Writer, filename string) (string, error) {
// // TODO use the tags and filters from the current context
// }
// InnerString renders the children to a string.
func (c renderContext) InnerString() (string, error) {
buf := new(bytes.Buffer)
@ -94,3 +91,26 @@ func (c renderContext) InnerString() (string, error) {
}
return buf.String(), nil
}
func (c renderContext) ParseTagArgs() (string, error) {
var args string
switch {
case c.node != nil:
args = c.node.Chunk.Args
case c.cn != nil:
args = c.cn.Chunk.Args
}
if strings.Contains(args, "{{") {
p, err := c.ctx.settings.Parse(args)
if err != nil {
return "", err
}
buf := new(bytes.Buffer)
err = p.Render(buf, c.ctx)
if err != nil {
return "", err
}
return buf.String(), nil
}
return args, nil
}

View File

@ -31,7 +31,7 @@ func Scan(data string, pathname string) []Chunk {
Type: ObjChunkType,
SourceInfo: si,
Source: source,
Parameters: data[m[2]:m[3]],
Args: data[m[2]:m[3]],
})
case '%':
c := Chunk{
@ -41,7 +41,7 @@ func Scan(data string, pathname string) []Chunk {
Name: data[m[4]:m[5]],
}
if m[6] > 0 {
c.Parameters = data[m[6]:m[7]]
c.Args = data[m[6]:m[7]]
}
out = append(out, c)
}

View File

@ -33,27 +33,27 @@ func TestScanner(t *testing.T) {
require.NotNil(t, tokens)
require.Len(t, tokens, 1)
require.Equal(t, ObjChunkType, tokens[0].Type)
require.Equal(t, "obj", tokens[0].Parameters)
require.Equal(t, "obj", tokens[0].Args)
tokens = Scan("{{ obj }}", "")
require.NotNil(t, tokens)
require.Len(t, tokens, 1)
require.Equal(t, ObjChunkType, tokens[0].Type)
require.Equal(t, "obj", tokens[0].Parameters)
require.Equal(t, "obj", tokens[0].Args)
tokens = Scan("{%tag args%}", "")
require.NotNil(t, tokens)
require.Len(t, tokens, 1)
require.Equal(t, TagChunkType, tokens[0].Type)
require.Equal(t, "tag", tokens[0].Name)
require.Equal(t, "args", tokens[0].Parameters)
require.Equal(t, "args", tokens[0].Args)
tokens = Scan("{% tag args %}", "")
require.NotNil(t, tokens)
require.Len(t, tokens, 1)
require.Equal(t, TagChunkType, tokens[0].Type)
require.Equal(t, "tag", tokens[0].Name)
require.Equal(t, "args", tokens[0].Parameters)
require.Equal(t, "args", tokens[0].Args)
for i, test := range scannerCountTests {
t.Run(fmt.Sprintf("%02d", i), func(t *testing.T) {

View File

@ -33,7 +33,7 @@ func parseLoopExpression(source string) (expressions.Expression, error) {
}
func loopTagParser(node chunks.ASTControlTag) (func(io.Writer, chunks.RenderContext) error, error) {
expr, err := parseLoopExpression(node.Parameters)
expr, err := parseLoopExpression(node.Args)
if err != nil {
return nil, err
}

View File

@ -28,7 +28,7 @@ func AddStandardTags(settings chunks.Settings) {
func captureTagParser(node chunks.ASTControlTag) (func(io.Writer, chunks.RenderContext) error, error) {
// TODO verify syntax
varname := node.Parameters
varname := node.Args
return func(w io.Writer, ctx chunks.RenderContext) error {
s, err := ctx.InnerString()
if err != nil {
@ -42,7 +42,7 @@ func captureTagParser(node chunks.ASTControlTag) (func(io.Writer, chunks.RenderC
func caseTagParser(node chunks.ASTControlTag) (func(io.Writer, chunks.RenderContext) error, error) {
// TODO parse error on non-empty node.Body
// TODO case can include an else
expr, err := expressions.Parse(node.Parameters)
expr, err := expressions.Parse(node.Args)
if err != nil {
return nil, err
}
@ -52,7 +52,7 @@ func caseTagParser(node chunks.ASTControlTag) (func(io.Writer, chunks.RenderCont
}
cases := []caseRec{}
for _, branch := range node.Branches {
bfn, err := expressions.Parse(branch.Parameters)
bfn, err := expressions.Parse(branch.Args)
if err != nil {
return nil, err
}
@ -82,7 +82,7 @@ func ifTagParser(polarity bool) func(chunks.ASTControlTag) (func(io.Writer, chun
test expressions.Expression
body *chunks.ASTControlTag
}
expr, err := expressions.Parse(node.Parameters)
expr, err := expressions.Parse(node.Args)
if err != nil {
return nil, err
}
@ -98,7 +98,7 @@ func ifTagParser(polarity bool) func(chunks.ASTControlTag) (func(io.Writer, chun
case "else":
// TODO parse error if this isn't the last branch
case "elsif":
t, err := expressions.Parse(c.Parameters)
t, err := expressions.Parse(c.Args)
if err != nil {
return nil, err
}