mirror of
https://github.com/danog/liquid.git
synced 2024-11-30 10:19:03 +01:00
Add RenderContext.ParseTagArgs
This commit is contained in:
parent
af95c44a25
commit
7c48138dad
@ -11,7 +11,7 @@ type Chunk struct {
|
|||||||
Type ChunkType
|
Type ChunkType
|
||||||
SourceInfo SourceInfo
|
SourceInfo SourceInfo
|
||||||
Name string // Name is the tag name of a tag Chunk. E.g. the tag name of "{% if 1 %}" is "if".
|
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.
|
Source string // Source is the entirety of the chunk, including the "{{", "{%", etc. markers.
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,9 +38,9 @@ func (c Chunk) String() string {
|
|||||||
case TextChunkType:
|
case TextChunkType:
|
||||||
return fmt.Sprintf("%s{%#v}", c.Type, c.Source)
|
return fmt.Sprintf("%s{%#v}", c.Type, c.Source)
|
||||||
case TagChunkType:
|
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:
|
case ObjChunkType:
|
||||||
return fmt.Sprintf("%s{%#v}", c.Type, c.Parameters)
|
return fmt.Sprintf("%s{%#v}", c.Type, c.Args)
|
||||||
default:
|
default:
|
||||||
return fmt.Sprintf("%s{%#v}", c.Type, c.Source)
|
return fmt.Sprintf("%s{%#v}", c.Type, c.Source)
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ func (c Chunk) MarshalYAML() (interface{}, error) {
|
|||||||
case TextChunkType:
|
case TextChunkType:
|
||||||
return map[string]interface{}{"text": c.Source}, nil
|
return map[string]interface{}{"text": c.Source}, nil
|
||||||
case TagChunkType:
|
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:
|
case ObjChunkType:
|
||||||
return map[string]interface{}{"obj": c.Name}, nil
|
return map[string]interface{}{"obj": c.Name}, nil
|
||||||
default:
|
default:
|
||||||
@ -33,7 +33,7 @@ func (c Chunk) MarshalYAML() (interface{}, error) {
|
|||||||
func (n ASTControlTag) MarshalYAML() (interface{}, error) {
|
func (n ASTControlTag) MarshalYAML() (interface{}, error) {
|
||||||
return map[string]map[string]interface{}{
|
return map[string]map[string]interface{}{
|
||||||
n.cd.name: {
|
n.cd.name: {
|
||||||
"args": n.Parameters,
|
"args": n.Args,
|
||||||
"body": n.Body,
|
"body": n.Body,
|
||||||
"branches": n.Branches,
|
"branches": n.Branches,
|
||||||
}}, nil
|
}}, nil
|
||||||
|
@ -45,7 +45,7 @@ func (s Settings) parseChunks(chunks []Chunk) (ASTNode, error) {
|
|||||||
rawTag.slices = append(rawTag.slices, c.Source)
|
rawTag.slices = append(rawTag.slices, c.Source)
|
||||||
}
|
}
|
||||||
case c.Type == ObjChunkType:
|
case c.Type == ObjChunkType:
|
||||||
expr, err := expressions.Parse(c.Parameters)
|
expr, err := expressions.Parse(c.Args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -82,7 +82,7 @@ func (s Settings) parseChunks(chunks []Chunk) (ASTNode, error) {
|
|||||||
ccd, ccn, ap = f.cd, f.cn, f.ap
|
ccd, ccn, ap = f.cd, f.cn, f.ap
|
||||||
}
|
}
|
||||||
} else if td, ok := s.FindTagDefinition(c.Name); ok {
|
} else if td, ok := s.FindTagDefinition(c.Name); ok {
|
||||||
f, err := td(c.Parameters)
|
f, err := td(c.Args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/osteele/liquid/expressions"
|
"github.com/osteele/liquid/expressions"
|
||||||
)
|
)
|
||||||
@ -16,10 +17,10 @@ type RenderContext interface {
|
|||||||
Evaluate(expr expressions.Expression) (interface{}, error)
|
Evaluate(expr expressions.Expression) (interface{}, error)
|
||||||
EvaluateString(source string) (interface{}, error)
|
EvaluateString(source string) (interface{}, error)
|
||||||
EvaluateStatement(tag, source string) (interface{}, error)
|
EvaluateStatement(tag, source string) (interface{}, error)
|
||||||
|
InnerString() (string, error)
|
||||||
|
ParseTagArgs() (string, error)
|
||||||
RenderChild(io.Writer, *ASTControlTag) error
|
RenderChild(io.Writer, *ASTControlTag) error
|
||||||
RenderChildren(io.Writer) error
|
RenderChildren(io.Writer) error
|
||||||
// RenderTemplate(io.Writer, filename string) (string, error)
|
|
||||||
InnerString() (string, error)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type renderContext struct {
|
type renderContext struct {
|
||||||
@ -82,10 +83,6 @@ func (c renderContext) RenderChildren(w io.Writer) error {
|
|||||||
return c.ctx.RenderASTSequence(w, c.cn.Body)
|
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.
|
// InnerString renders the children to a string.
|
||||||
func (c renderContext) InnerString() (string, error) {
|
func (c renderContext) InnerString() (string, error) {
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
@ -94,3 +91,26 @@ func (c renderContext) InnerString() (string, error) {
|
|||||||
}
|
}
|
||||||
return buf.String(), nil
|
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
|
||||||
|
}
|
||||||
|
@ -31,7 +31,7 @@ func Scan(data string, pathname string) []Chunk {
|
|||||||
Type: ObjChunkType,
|
Type: ObjChunkType,
|
||||||
SourceInfo: si,
|
SourceInfo: si,
|
||||||
Source: source,
|
Source: source,
|
||||||
Parameters: data[m[2]:m[3]],
|
Args: data[m[2]:m[3]],
|
||||||
})
|
})
|
||||||
case '%':
|
case '%':
|
||||||
c := Chunk{
|
c := Chunk{
|
||||||
@ -41,7 +41,7 @@ func Scan(data string, pathname string) []Chunk {
|
|||||||
Name: data[m[4]:m[5]],
|
Name: data[m[4]:m[5]],
|
||||||
}
|
}
|
||||||
if m[6] > 0 {
|
if m[6] > 0 {
|
||||||
c.Parameters = data[m[6]:m[7]]
|
c.Args = data[m[6]:m[7]]
|
||||||
}
|
}
|
||||||
out = append(out, c)
|
out = append(out, c)
|
||||||
}
|
}
|
||||||
|
@ -33,27 +33,27 @@ func TestScanner(t *testing.T) {
|
|||||||
require.NotNil(t, tokens)
|
require.NotNil(t, tokens)
|
||||||
require.Len(t, tokens, 1)
|
require.Len(t, tokens, 1)
|
||||||
require.Equal(t, ObjChunkType, tokens[0].Type)
|
require.Equal(t, ObjChunkType, tokens[0].Type)
|
||||||
require.Equal(t, "obj", tokens[0].Parameters)
|
require.Equal(t, "obj", tokens[0].Args)
|
||||||
|
|
||||||
tokens = Scan("{{ obj }}", "")
|
tokens = Scan("{{ obj }}", "")
|
||||||
require.NotNil(t, tokens)
|
require.NotNil(t, tokens)
|
||||||
require.Len(t, tokens, 1)
|
require.Len(t, tokens, 1)
|
||||||
require.Equal(t, ObjChunkType, tokens[0].Type)
|
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%}", "")
|
tokens = Scan("{%tag args%}", "")
|
||||||
require.NotNil(t, tokens)
|
require.NotNil(t, tokens)
|
||||||
require.Len(t, tokens, 1)
|
require.Len(t, tokens, 1)
|
||||||
require.Equal(t, TagChunkType, tokens[0].Type)
|
require.Equal(t, TagChunkType, tokens[0].Type)
|
||||||
require.Equal(t, "tag", tokens[0].Name)
|
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 %}", "")
|
tokens = Scan("{% tag args %}", "")
|
||||||
require.NotNil(t, tokens)
|
require.NotNil(t, tokens)
|
||||||
require.Len(t, tokens, 1)
|
require.Len(t, tokens, 1)
|
||||||
require.Equal(t, TagChunkType, tokens[0].Type)
|
require.Equal(t, TagChunkType, tokens[0].Type)
|
||||||
require.Equal(t, "tag", tokens[0].Name)
|
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 {
|
for i, test := range scannerCountTests {
|
||||||
t.Run(fmt.Sprintf("%02d", i), func(t *testing.T) {
|
t.Run(fmt.Sprintf("%02d", i), func(t *testing.T) {
|
||||||
|
@ -33,7 +33,7 @@ func parseLoopExpression(source string) (expressions.Expression, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func loopTagParser(node chunks.ASTControlTag) (func(io.Writer, chunks.RenderContext) error, 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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
10
tags/tags.go
10
tags/tags.go
@ -28,7 +28,7 @@ func AddStandardTags(settings chunks.Settings) {
|
|||||||
|
|
||||||
func captureTagParser(node chunks.ASTControlTag) (func(io.Writer, chunks.RenderContext) error, error) {
|
func captureTagParser(node chunks.ASTControlTag) (func(io.Writer, chunks.RenderContext) error, error) {
|
||||||
// TODO verify syntax
|
// TODO verify syntax
|
||||||
varname := node.Parameters
|
varname := node.Args
|
||||||
return func(w io.Writer, ctx chunks.RenderContext) error {
|
return func(w io.Writer, ctx chunks.RenderContext) error {
|
||||||
s, err := ctx.InnerString()
|
s, err := ctx.InnerString()
|
||||||
if err != nil {
|
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) {
|
func caseTagParser(node chunks.ASTControlTag) (func(io.Writer, chunks.RenderContext) error, error) {
|
||||||
// TODO parse error on non-empty node.Body
|
// TODO parse error on non-empty node.Body
|
||||||
// TODO case can include an else
|
// TODO case can include an else
|
||||||
expr, err := expressions.Parse(node.Parameters)
|
expr, err := expressions.Parse(node.Args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -52,7 +52,7 @@ func caseTagParser(node chunks.ASTControlTag) (func(io.Writer, chunks.RenderCont
|
|||||||
}
|
}
|
||||||
cases := []caseRec{}
|
cases := []caseRec{}
|
||||||
for _, branch := range node.Branches {
|
for _, branch := range node.Branches {
|
||||||
bfn, err := expressions.Parse(branch.Parameters)
|
bfn, err := expressions.Parse(branch.Args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -82,7 +82,7 @@ func ifTagParser(polarity bool) func(chunks.ASTControlTag) (func(io.Writer, chun
|
|||||||
test expressions.Expression
|
test expressions.Expression
|
||||||
body *chunks.ASTControlTag
|
body *chunks.ASTControlTag
|
||||||
}
|
}
|
||||||
expr, err := expressions.Parse(node.Parameters)
|
expr, err := expressions.Parse(node.Args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -98,7 +98,7 @@ func ifTagParser(polarity bool) func(chunks.ASTControlTag) (func(io.Writer, chun
|
|||||||
case "else":
|
case "else":
|
||||||
// TODO parse error if this isn't the last branch
|
// TODO parse error if this isn't the last branch
|
||||||
case "elsif":
|
case "elsif":
|
||||||
t, err := expressions.Parse(c.Parameters)
|
t, err := expressions.Parse(c.Args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user